1

JPanelでのコンポーネントの表示について混乱しています。

次のように、0.8fの半透明度を持つカスタムJPanelを作成するとします:-

JPanel panel=new JPanel(){
        @Override
        public void paint(Graphics g)
        {
            super.paint(g);
            BufferedImage img=(BufferedImage)createImage(getWidth(),getHeight());
            Graphics2D g2=(Graphics2D) g.create();
            g2.setComposite(AlphaComposite.SrcOver.derive(0.8f));
            g2.drawImage(img,0,0,null);
        }
        @Override
        public Dimension getPreferredSize()
        {
            return new Dimension(300,300);
        }
    };

これをフレームのcontentPaneとして設定します。

frame.setContentPane(panel);

今、私はそれにいくつかのボタンを追加します。

    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));
    frame.add(new JButton("Click Here"));

1)次に、出力で半透明のボタンが表示されるのはなぜですか?JPanelは単層であり、paintメソッドをオーバーライドしてからボタンを追加したときに最初に半透明のイメージをペイントしたため、ボタンが半透明であってはなりません。

2)また、これらの4つのボタンのうち、2つだけが半透明です。なぜそのような偏りがあるのですか?

3)これらの4つのボタンを追加する前にテーブルも追加すると、すべてが半透明になります。なぜですか。

Object[] names = new Object[] {
             "Title", "Artist", "Album"
         };
         String[][] data = new String[][] {
             { "Los Angeles", "Sugarcult", "Lights Out" },
             { "Do It Alone", "Sugarcult", "Lights Out" },
             { "Made a Mistake", "Sugarcult", "Lights Out" },
             { "Kiss You Better", "Maximo Park", "A Certain Trigger" },
             { "All Over the Shop", "Maximo Park", "A Certain Trigger" },
             { "Going Missing", "Maximo Park", "A Certain Trigger" }
         };
         JTable table = new JTable(data, names);
         frame.add(table); 

4)paintComponent(Graphics g)JPanelに使用する場合、テーブルを追加するかどうか、またはボタンをいくつ追加するかにかかわらず、何も半透明ではありません。なぜですか。

(アプリケーションを実行するとすぐに出力されるかどうかを尋ねています。マウスをこれらのボタンの上に置いたり、テーブルのいずれかの行をクリックすると不透明になることを知っています。これは、Swingのペイントメカニズムによるものです。)

4

2 に答える 2

4

1)では、出力で半透明のボタンが表示されるのはなぜですか?JPanelは単層であり、ペイント方法をオーバーライドしてからボタンを追加したときに最初に半透明のイメージをペイントしたので、ボタンが上に来るようにボタンが半透明であってはなりません。

実際には、ボタンの上に半透明の効果をペイントしました。 paint呼び出し

  • paintComponent
  • paintBorder
  • paintChildren

次に、すでにペイントされているもの(子供)の上に半透明のエフェクトをペイントしました。コンポーネントを追加しても違いはありません。Swingはさまざまな状況でコンポーネントをペイントします。最初の状況は、コンポーネントが最初に実現されたとき(画面に表示されたとき)であり、ダーティ領域(およびロット)の変更に応じて行われます。他の人の)...あなたの自己をだましてはいけません、あなたはこれを制御することはできません...

ペイントプロセスをレイヤリングアプローチと考えてください。最初に背景をペイントし、次に中間の地面をペイントし、最後に前の地面をペイントします。次に、前の地面をペイントします。

ここに画像の説明を入力してください

public class TestTranslucentControls {

    public static void main(String[] args) {
        new TestTranslucentControls();
    }

    public TestTranslucentControls() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage background;

        public TestPane() {
            setLayout(new GridBagLayout());
            try {
                background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/poster.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            add(new JButton("1"));
            add(new JButton("2"));
            add(new JButton("3"));
            add(new JButton("4"));
            add(new JButton("5"));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setComposite(AlphaComposite.SrcOver.derive(0.25f));
                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;
                g2.drawImage(background, x, y, this);
                g2.dispose();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(300, 300) : new Dimension(background.getWidth(), background.getHeight());
        }
    }
}

私はあなたが見つけるかもしれないと思います...

使える ;)

于 2013-01-07T23:50:55.873 に答える
1

paintComponent()通常、ではなくオーバーライドする必要がありますpaint()。これが透明性の問題の原因である可能性があります。次に、おそらくレイアウトを変更したいと思うでしょう。デフォルトでは、パネルはFlowLayoutを使用します。BorderLayoutまたはGridBagLayout、あるいはその2つを組み合わせて使用​​することをお勧めします。

于 2013-01-07T18:24:32.777 に答える