2009-02-12 99 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); 

    } 
} 

斯科特>我已经受过教育:-)感谢