2009-02-12 76 views
1

位奇怪的,如果看到我做到以下幾點:的Java Swing - 在使用佈局奇怪不同的佈局管理器

import javax.swing.*; 
public class FunkyButtonLayout { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(""); 
     JPanel j0 = new JPanel();  // j0 gets added to the root pane 
     j0.setLayout(null); 
     JPanel j1 = new JPanel();  // j1 gets added to j0 
     j1.setLayout(null); 
     JButton b1 = new JButton(""); // b1 gets added to j1 
     j1.add(b1); 
     b1.setBounds(0, 0, 40, 32); // b1 is big 
     j0.add(j1); 
     j1.setBounds(0, 0, 32, 32); // j1 is not so big - b1 gets 'trimmed' 
     frame.getContentPane().setLayout(null); // <- seems to be needed :-(
     frame.getContentPane().add(j0);    
     j0.setBounds(10, 10, 32, 32); // end result: a 32x32 button with 
     frame.setSize(125, 125);  // a trimmed right border 
     frame.setVisible(true);  // in the top-left corner 
    } 
} 

我得到差不多就是我要找的,除了在定位J0的能力帶有佈局管理器的根窗格。如果我改變

 frame.getContentPane().setLayout(null); 

 frame.getContentPane().setLayout(new java.awt.FlowLayout()); 

我看到J0畫爲1x1像素@屏幕中間:-(

任何想法,爲什麼?請注意,這ISN」只是一個FlowLayout的東西 - 幾乎所有的佈局管理器弄亂了這一點。

我真的想要「邊界修剪在一邊」按鈕的淨效應 - 它允許我做工具欄按鈕集羣的事情(cage fighter試圖擺脫的東西)與本機外觀按鈕控制 - 我看不到另一種方式做到這一點,感謝OS級皮膚。因此,任何想法讚賞:-)

回答

4

如果您將佈局管理器設置爲null,您必須顯式設置容器的首選大小(這就是爲什麼它顯示如此之小)。

如果您在組件上使用setBounds,那麼您將覆蓋父容器的佈局管理器所做的工作。

我將刪除所有對setBounds和所有對setLayout(null)的調用的調用,並嘗試使用佈局管理器後的效果。

+0

你達人!那麼,幾乎;-)「按照他們打算使用的方式使用佈局管理器」並不會給我帶來我所需要的破解。 但是,添加\t j0.setPreferredSize(new java.awt.Dimension(32,32));在j0.setBounds行解決問題之後。 謝謝!!!!! – 2009-02-12 01:23:21

1

...任何想法爲什麼?

是的。發生這種情況是因爲當你移除佈局管理器(通過設置爲空)時,你正在對計算機說:「我會去做所有的鋪設工作」;而使用任何其他佈局管理器將嘗試......以及根據您的需求佈置您的組件(根據要鋪設的對象的屬性)

所以,我認爲這會好得多,而不是嘗試創建一個Border實例並將其設置到JButton中,而不是試圖調整它周圍的所有對象。

我會看看我能不能快速提出一些事情。

編輯:

哎呀,這不是任何快,但在這裏它是(我搞砸了,這是討厭我1px的線) alt text http://img22.imageshack.us/img22/8933/capturaby8.png

正如我之前說的,將佈局設置爲空不是最好的方法。最好是創建一個自定義邊框並將其設置爲按鈕(或設置空邊框)。

下面的代碼:

import javax.swing.*; 
import java.awt.*; 
import javax.swing.border.*; 
import java.awt.geom.*; 

/** 
* Sample usage of swing borders. 
* @author <a href="http://stackoverflow.com/users/20654">Oscar Reyes</a> 
*/ 
public class ButtonBorderSample { 

    public static void main(String [] args) { 

     // Pretty standard swing code 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     JPanel panel = new JPanel(new FlowLayout( 
             FlowLayout.CENTER, 0, 5)); 


     panel.add(createButton("F I R S T")); 
     panel.add(createButton("S E C O N D")); 
     panel.add(createButton("T H I R D ")); 

     frame.add(panel , BorderLayout.NORTH); 

     frame.pack(); 
     frame.setVisible(true); 

    } 
    /** 
    * Utility method to create a button. 
    * Creates the button, make it square, and add our custom border. 
    */ 
    private static JButton createButton(String s) { 
     JButton b = new JButton(s); 
     b.setPreferredSize(new Dimension(100, 100 )); 
     b.setBorder(new NoGapBorder()); 
     return b; 
    } 
} 

/** 
* This border implementation. It doesn't have insets and draws only a 
* few parts of the border 
* @author <a href="http://stackoverflow.com/users/20654">Oscar Reyes</a> 
*/ 
class NoGapBorder implements Border { 

    private final Insets insets = new Insets(-1, -1 , -1, -1); 

    /** 
    * Defines in Border interface. 
    * @return The default insets instace that specifies no gap at all. 
    */ 
    public Insets getBorderInsets(Component c) { 
     return insets; 
    } 


    /** 
    * Defines in Border interface. 
    * @return false always, it is not relevant. 
    */ 
    public boolean isBorderOpaque() { 
     return false; 
    } 

    /** 
    * Paint the border for the button. 
    * This creates the difference between setting the border to null 
    * and using this class. 
    * It only draws a line in the top, a line in the bottom and a 
    * darker line 
    * in the left, to create the desired effect. 
    * A much more complicated strtegy could be used here. 
    */ 
    public void paintBorder(Component c, Graphics g, 
          int x, int y, int width, int height) { 

     Color oldColor = g.getColor(); 
     int h = height; 
     int w = width; 

     g.translate(x, y); 

     // Color for top and bottom 
     g.setColor(c.getBackground().brighter()); 

     // draw top line 
     g.drawLine(1, 0, w-2, 0); 

     // draw bottom line 
     g.drawLine(0, h-1, w-1, h-1); 

     // change the color to make it look as a division 
     g.setColor(c.getBackground().darker()); 

     // draw the left line 
     g.drawLine(0, 0, 0, h-2);   

     // set the graphics back to its original state. 
     g.translate(-x, -y); 
     g.setColor(oldColor); 

    } 

} 

編輯

戴夫卡爾佩內託寫道:

**奧斯卡> ***不幸的是這個停止工作,一旦你UIManager.setLookAndFeel(UIManager的.getSystemLookAndFeelClassName()); ,這也是我的需求的核心(我正在尋找儘可能原生的外觀)。*

嗯,我沒有試圖做你的工作,而是回答你的問題,你認爲你的問題與LayoutManagers有關,我說這不是問題。也許我應該停下來,但是我的「程序員」癢讓我繼續這個樣本。 :)

我很高興你在最後解決你的問題。)

+0

也許我應該已經停在那裏 Reely,很高興你沒有 - 我從你介紹的代碼中學到了很多東西 - 謝謝:-) – 2009-02-13 21:05:18

0

你好 - 感謝大家的協助。

丹>這是您的意見首選佈局,讓我得到這個工作 - 增加j0.setPreferredSize(new java.awt.Dimension(32, 32));是所需的所有這一切的工作。

奧斯卡>可惜這一次,停止你UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());工作,同時這也是核心我的需要(我希望讓這個看起來像是天然越好)。

例如,這裏是我的,看上去像個XP 3個按鈕:

alt text http://img19.imageshack.us/img19/8595/minems5.png

...這裏就是你看起來像用XP的外觀:

alt text http://img102.imageshack.us/img102/5412/yoursod4.png

...不幸的是,這不是一回事 - 對不起,我的要求沒有更清楚:-(

FWIW,這裏的代碼(圖像是透明的圖標的大小與按鈕相同,與垂直線作爲圖標的一部分):

import java.awt.*; 
import javax.swing.*; 

public class FunkyButtonLayout { 
    public static void main(String[] args) { 
    try { 
     UIManager.setLookAndFeel(
      UIManager.getSystemLookAndFeelClassName()); 
    } catch (Exception e) { 

    } 

    JFrame frame = new JFrame("x"); 
    Container y = frame.getContentPane(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    y.setLayout(new FlowLayout()); 

    JPanel uberButton = new JPanel(); 
    uberButton.setLayout(null); 
    uberButton.setSize(98, 32); 
    uberButton.setPreferredSize(new Dimension(98, 32)); 

    JButton record = new JButton(new ImageIcon("img/record.png")); 
    record.setBounds(0, 0, 40, 32); 
    record.setEnabled(true); 
    record.setFocusPainted(false); 
    JPanel _record = new JPanel(); 
    _record.setLayout(null); 
    _record.setBounds(0, 0, 33, 32); 

    JButton pause = new JButton(new ImageIcon("img/pause.png")); 
    pause.setBounds(-4, 0, 44, 32); 
    pause.setEnabled(true); 
    pause.setFocusPainted(false); 
    JPanel _pause = new JPanel(); 
    _pause.setLayout(null); 
    _pause.setBounds(33, 0, 33, 32); 

    JButton stop = new JButton(new ImageIcon("img/stop.png")); 
    stop.setBounds(-4, 0, 36, 32); 
    stop.setEnabled(true); 
    stop.setFocusPainted(false); 
    JPanel _stop = new JPanel(); 
    _stop.setLayout(null); 
    _stop.setBounds(66, 0, 32, 32); 

    _record.add(record); 
    _pause.add(pause); 
    _stop.add(stop); 

    uberButton.add(_record); 
    uberButton.add(_pause); 
    uberButton.add(_stop); 

    y.add(uberButton); 

    frame.pack(); 

    frame.setVisible(true); 

    } 
} 

斯科特>我已經受過教育:-)感謝