亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果兩個組件大小相同且全屏,則 JLayeredPane 不會繪制低組件

如果兩個組件大小相同且全屏,則 JLayeredPane 不會繪制低組件

蠱毒傳說 2021-12-10 10:07:36
JLayeredPane 如果兩個組件大小相同且全屏,則不繪制低組件軟件工作原理:JFrame <- APanel <- JLayeredPane <-(分層子組件)我的軟件是全屏軟件。APanel 是 BorderLayout 組件。JLayeredPane 是 APanel 中的 BorderLayout.CENTERPanel1 gp = new Panel1(); //Panel1 extends JPanelgp.setSize(jlp.getSize());jlp.add(gp);gp.initializeDisplay(); //starts repaint() loopjlp.setLayer(gp, 90);Panel2 lp = new Panel2(); //Panel2 extends JPanellp.setSize(jlp.getSize());lp.initializeDisplay();  //starts repaint() looplp.initializeComponents(); //Adds and moves componentsjlp.add(lp);jlp.setLayer(lp, 110);當我這樣制作時,只Panel2顯示。Panel1的paintComponent()這個樣子的(只需繪制圖像):g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);Panel2包含很多按鈕和標簽。這個方法解決了這個問題。Panel1 gp = new Panel1();gp.setSize(jlp.getSize());jlp.add(gp);gp.initializeDisplay();jlp.setLayer(gp, 90);Panel2 lp = new Panel2();lp.setSize(jlp.getWidth() - 1, jlp.getHeight() - 1); //Changed herelp.initializeDisplay();lp.initializeComponents();jlp.add(lp);jlp.setLayer(lp, 110);但是這種方法又引起了問題:Dimension cs = new Dimension(jlp.getWidth() - 1, jlp.getHeight() - 1);GrassPane gp = new GrassPane();gp.setSize(cs);jlp.add(gp);gp.initializeDisplay();jlp.setLayer(gp, 90);LobbyPane lp = new LobbyPane(this);lp.setSize(cs);lp.initializeDisplay();lp.initializeComponents();jlp.add(lp);jlp.setLayer(lp, 110);如果您需要更多信息(例如代碼),請添加評論。
查看完整描述

1 回答

?
交互式愛情

TA貢獻1712條經驗 獲得超3個贊

當一個不透明組件與另一個組件重疊時,有意跳過繪制完全模糊的組件。當組件被錯誤地聲明為不透明時,這只會成為一個問題。因此,當您實現自己的組件繪制透明圖像時,它們應該實現isOpaque()返回false.


有趣的是,我仍然可以使用以下代碼重現透明組件的重繪問題:


JFrame f = new JFrame("Test");

JLayeredPane pane = f.getLayeredPane();

JButton b = new JButton("Normal Text");

b.setHorizontalTextPosition(SwingConstants.LEFT);

b.setBounds(20, 20, 300, 100);

JLabel l = new JLabel("Overlay");

l.setHorizontalTextPosition(SwingConstants.RIGHT);

l.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));

l.setBounds(20, 20, 300, 100);

l.setOpaque(false);

pane.add(l);

pane.add(b);

f.setSize(350, 200);

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setVisible(true);

在這里,文本“Overlay”最初可能會也可能不會出現,但是一旦按鈕的屬性之一發生變化(例如接收焦點或被點擊),文本就會消失。


問題在于以下屬性:


System.out.println(pane.isOptimizedDrawingEnabled());

將打印true?!皟灮L圖”意味著在某些情況下可能無法渲染某些子項。正如文檔所說:


如果此組件平鋪其子級,即,如果它可以保證子級不會重疊,則返回 true。


當然,JLayeredPane永遠不會平鋪子項,而是將它們堆疊在一起并且永遠不能保證它們不會重疊。盡管如此,出于某種原因,Swing 開發人員還是決定實現以下邏輯:


private void validateOptimizedDrawing() {

    boolean layeredComponentFound = false;

    synchronized(getTreeLock()) {

        Integer layer;


        for (Component c : getComponents()) {

            layer = null;


            if(SunToolkit.isInstanceOf(c, "javax.swing.JInternalFrame") ||

                   (c instanceof JComponent &&

                    (layer = (Integer)((JComponent)c).

                                 getClientProperty(LAYER_PROPERTY)) != null))

            {

                if(layer != null && layer.equals(FRAME_CONTENT_LAYER))

                    continue;

                layeredComponentFound = true;

                break;

            }

        }

    }


    if(layeredComponentFound)

        optimizedDrawingPossible = false;

    else

        optimizedDrawingPossible = true;

}

因此,每當組件不是JComponent實例或沒有LAYER_PROPERTY屬性時(在使用上述示例中的默認圖層時總是如此),盡管實際布局邏輯中沒有任何更改,窗格仍會決定優化繪制是可能的。


所以當我們改變


pane.add(l);

pane.add(b);


Object myLayer = JLayeredPane.DEFAULT_LAYER+1;

pane.add(l, myLayer);

pane.add(b, myLayer);

問題將消失,現在System.out.println(pane.isOptimizedDrawingEnabled());將打印false。


小心自動裝箱。當您使用pane.add(l, JLayeredPane.DEFAULT_LAYER+1);or just 時pane.add(l, 1);,它會調用add(Component comp, int index)而不是所需的add(Component comp, Object constraints).


查看完整回答
反對 回復 2021-12-10
  • 1 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號