4

NimbiusがsetOpaque()を他のJavaLaFとは異なる方法で処理する理由を誰かが説明できますか。通常は透過的であるコンポーネントはもはや透過的ではないため、コードが壊れています。

編集:問題はJTextAreas(私が必要としているものです)または同様のコンポーネントのみを扱っているようです。

編集編集:これは実際のアプリケーションの画面です。trashgodのソリューションを適用しても、背景が透けて見えません。

代替テキスト

編集編集編集:
paint()をオーバーライドするためにtrashgodの提案を試しました。私はこれで何時間も苦労しました、そしてそれを動かすことができませんでした。背景が透けて見えるようにすることはできましたが、JinternalFrameを移動したり、サイズを変更したり、テキストを選択したりすることができませんでした。super.paint(g)を呼び出すと、解決策を解決できませんでした。私が行方不明になっているかもしれないこれを行う簡単な方法はありますか?
私はこれに新しいアプローチを取りました。JInternalFrameの内部には、JLayeredPaneがあります。
レイヤー0-JLabel
レイヤー1-JTextArea

JInternalFrameが移動またはサイズ変更された場合:

  1. 自分自身を見えなくする
  2. コンテナ内のどこにあるかをスクリーンショットで撮ります
  3. 撮影した画像でJLabelをペイントします
  4. 自分自身を再び表示します。

JInternalFrameをまったく透過的にすることができなかったので。その透明性をシミュレートしました。唯一の問題は、これに関連する多くのオーバーヘッドがあることです。何かご意見は?

代替テキスト


package newpackage;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.UIManager;

/**
 * Example of how to create a transparent internal frame.
 * @author dvargo
 */
public class TransparentInternalFrame extends JInternalFrame {

    JLayeredPane container;


    /**
     * Defualt constructor to set the frame up
     * @param container The container for the frame
     * @param opacity The opacity of the frame
     */
    public TransparentInternalFrame(JLayeredPane container, int opacity) {
        super("", true, true, true, true);
        this.container = container;
        initComponents();
        setSize(200, 200);
        putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
        scrollPane.setBackground(new Color(0, 0, 0, opacity));
        scrollPane.getViewport().setBackground(new Color(0, 0, 0, opacity));
        textArea.setBackground(new Color(0, 0, 0, opacity));
        setBG();
    }

    /**
     * Builds the GUI
     */
    private void initComponents() {

        layeredPane = new javax.swing.JLayeredPane();
        imageLabel = new javax.swing.JLabel();
        scrollPane = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();

        imageLabel.setBounds(0, 0, 360, 260);
        layeredPane.add(imageLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);

        scrollPane.setBorder(null);

        textArea.setColumns(20);
        textArea.setRows(5);
        textArea.addKeyListener(new java.awt.event.KeyAdapter() {

            public void keyPressed(java.awt.event.KeyEvent evt) {
                textAreaKeyPressed(evt);
            }

            public void keyReleased(java.awt.event.KeyEvent evt) {
                textAreaKeyReleased(evt);
            }

            public void keyTyped(java.awt.event.KeyEvent evt) {
                textAreaKeyTyped(evt);
            }
        });

        addComponentListener(new java.awt.event.ComponentAdapter() {

            public void componentMoved(java.awt.event.ComponentEvent evt) {
                frameMoved();
            }

            public void componentResized(java.awt.event.ComponentEvent evt) {
                frameResized();
            }
        });

        scrollPane.setViewportView(textArea);

        scrollPane.setBounds(0, 0, 360, 260);
        layeredPane.add(scrollPane, javax.swing.JLayeredPane.PALETTE_LAYER);



        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
       getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 362, javax.swing.GroupLayout.PREFERRED_SIZE));
        layout.setVerticalGroup(
              layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE));
    }

    /**
     * The text will be blurred with out this
     * @param evt
     */
    private void textAreaKeyTyped(java.awt.event.KeyEvent evt) {
        repaintAll();
    }

    /**
     * The text will be blurred with out this
     * @param evt
     */
    private void textAreaKeyPressed(java.awt.event.KeyEvent evt) {
        repaintAll();
    }

    /**
     * The text will be blurred with out this
     * @param evt
     */
    private void textAreaKeyReleased(java.awt.event.KeyEvent evt) {
        repaintAll();
    }

    /**
     * Capture whats behind the frame and paint it to the image label
     */
    private void setBG() {

        setVisible(false);
        Rectangle location = new Rectangle(this.getX() + container.getX(),
                this.getY() + container.getY(),
                (int) this.getSize().getWidth() + 8 + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getWidth(),
                (int) this.getSize().getHeight() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight() + 4);
        ImageIcon newIcon = new ImageIcon(createImage((JComponent) container, location));
        setVisible(true);
        imageLabel.setIcon(newIcon);
        repaint();
    }

    /**
     * Only need to update the image label if the frame is moved or resized
     */
    private void frameResized() {
        setBG();
        textArea.repaint();
    }

    /**
     * Only need to update the image label if the frame is moved or resized
     */
    private void frameMoved() {
        setBG();
        for(Component x : container.getComponents())
        {
            //see if its a jinternalframe
            if(x.getClass().getName().equals(this.getClass().getName()))
            {
                //cast it
                TransparentInternalFrame temp = (TransparentInternalFrame)x;
                //make sure its not the same one as this
                if(x.getBounds().equals(this.getBounds()))
                {
                    return;
                }
                //if they intersect
                if(x.getBounds().intersects(this.getBounds()))
                {
                    this.setVisible(false);
                    temp.setBG();
                    this.setVisible(true);
                }
            }
        }

        textArea.repaint();
    }

    private void repaintAll() {
        textArea.repaint();
        imageLabel.repaint();
        layeredPane.repaint();
        scrollPane.repaint();
        scrollPane.getViewport().repaint();
        textArea.repaint();
        repaint();
    }

    /**
     *  Create a BufferedImage for Swing components.
     *  All or part of the component can be captured to an image.
     *
     *  @param  component Swing component to create image from
     *  @param  region The region of the component to be captured to an image
     *  @return image the image for the given region
     */
    public static BufferedImage createImage(JComponent component, Rectangle region) {
        //  Make sure the component has a size and has been layed out.
        //  (necessary check for components not added to a realized frame)

        if (!component.isDisplayable()) {
            Dimension d = component.getSize();

            if (d.width == 0 || d.height == 0) {
                d = component.getPreferredSize();
                component.setSize(d);
            }

            layoutComponent(component);
        }

        BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();

        //  Paint a background for non-opaque components,
        //  otherwise the background will be black

        if (!component.isOpaque()) {
            g2d.setColor(component.getBackground());
            g2d.fillRect(region.x, region.y, region.width, region.height);
        }

        g2d.translate(-region.x, -region.y);
        component.paint(g2d);
        g2d.dispose();
        return image;
    }

    public static void layoutComponent(Component component) {
        synchronized (component.getTreeLock()) {
            component.doLayout();

            if (component instanceof Container) {
                for (Component child : ((Container) component).getComponents()) {
                    layoutComponent(child);
                }
            }
        }
    }
    private javax.swing.JLabel imageLabel;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JLayeredPane layeredPane;
    private javax.swing.JTextArea textArea;


    public static void main(String args[])
    {
        try
        {
            UIManager.setLookAndFeel(
                "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        JFrame container = new JFrame();
        container.setSize(800, 800);

        JLayeredPane layerPanel = new JLayeredPane();
        layerPanel.setSize(800, 800);
        container.getContentPane().add(layerPanel);
        layerPanel.setVisible(true);

        JPanel colorPanel = new JPanel();
        colorPanel.setSize(800,800);
        colorPanel.setBackground(Color.red);
        layerPanel.add(colorPanel);
        layerPanel.setLayer(colorPanel, JLayeredPane.DEFAULT_LAYER);

        TransparentInternalFrame frameA = new TransparentInternalFrame(layerPanel,0);
        frameA.setVisible(true);
        layerPanel.add(frameA);
        layerPanel.setLayer(frameA, 1);
        frameA.setSize(282,282);

        TransparentInternalFrame frameB = new TransparentInternalFrame(layerPanel, 0);
        frameB.setVisible(true);
        layerPanel.add(frameB);
        layerPanel.add(frameB,1);
        frameB.setLocation(300, 300);
        frameB.setSize(282,282);

        container.repaint();
        container.setVisible(true);

    }
}


4

2 に答える 2

12

記事AWT と Swing でのペイントの不透明度に関するセクションから、ある程度の洞察が得られるかもしれません。特に、 opaque プロパティを設定しても、「コンポーネントの背景を透明にする」という意味ではありません。問題を実証するsscceも有益な場合があります。

補遺:例を単純化すると、テキスト領域自体を透明にできるように見えますが、ニンバスのデフォルトは領域の境界に影響を与えています。それに応じてそれらを変更してみてください。

コードに関するいくつかの注意事項:

  • 常にイベント ディスパッチ スレッドで GUI を構築します。
  • 他スレから引っ張らないでください。
  • 例外を飲み込まないでください。

補遺: への変更を参照してくださいcreate()

isPalette補遺: あなたも物件を見たいと思うかもしれません

jif.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);

代替テキスト

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JInternalFrame;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;

public class TransparentTextArea extends JTextArea {

    int alpha;

    public TransparentTextArea(int alpha) {
        super(4, 16);
        this.alpha = alpha;
        this.setBackground(new Color(0, 0, 0, alpha));
        this.setFont(new Font("Serif", Font.ITALIC, 24));
        this.setEditable(false);
        this.setText("Twas brillig and the slithy toves,\n"
            + "Did gyre and gimble in the wabe;\n"
            + "All mimsy were the borogoves,\n"
            + "And the mome raths outgrabe.");
    }

    private static void create() {
        JFrame f = new JFrame();
        f.setLayout(new FlowLayout());
        f.getContentPane().setBackground(new Color(0xffffc0));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JInternalFrame jif = new JInternalFrame();
        JPanel panel = new JPanel();
        panel.setBackground(new Color(0xffffc0));
        panel.add(new TransparentTextArea(0));
        jif.add(panel);
        jif.setVisible(true);

        f.add(jif);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {

        try {
            UIManager.setLookAndFeel(
                "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception e) {
            e.printStackTrace();
        }

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                create();
            }
        });
    }
}
于 2010-11-03T20:22:35.073 に答える
1

hereで説明されているように、setOpaque は、ユーザーが思っていることを実行せず、その失敗は Nimbus で明らかになります。アルファ色を参照する他の答えは、あなたが望むものを達成するための正しい方法です。

于 2010-11-08T03:18:51.343 に答える