java swing-使用不同布局管理器时的布局异常
有点奇怪,如果我这样做:java swing-使用不同布局管理器时的布局异常,java,swing,layout,Java,Swing,Layout,有点奇怪,如果我这样做: 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)
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
}
}
排队
frame.getContentPane().setLayout(new java.awt.FlowLayout());
我将j0绘制为屏幕中间的1x1像素:-
你知道为什么吗?请注意,这不仅仅是一个FlowLayout问题——几乎每个布局管理器都会把它搞砸
我真的很想拥有“在一边修剪边框”按钮的净效果——它允许我做工具栏按钮集群的事情,这种事情试图摆脱原生外观的按钮控件——由于操作系统级别的皮肤,我看不到另一种做这件事的方法。因此,任何想法都值得赞赏:-如果将布局管理器设置为null,则必须明确设置容器的首选大小,这就是为什么它显示得如此小 如果要在组件上使用收进边界,则会超出父容器布局管理器所做的工作
我将删除对setBounds的所有调用和对setLayoutnull的所有调用,并尝试在仅使用布局管理器后达到您的效果。如果将布局管理器设置为null,则必须明确设置容器的首选大小,这就是它显示得如此小的原因 如果要在组件上使用收进边界,则会超出父容器布局管理器所做的工作 我将删除对setBounds的所有调用和对setLayoutnull的所有调用,并尝试在仅使用布局管理器后实现您的效果 …知道为什么吗 对。这是因为当你将布局管理器设置为null来删除布局管理器时,你是在对计算机说,我将负责所有的布局工作;在使用任何其他LayoutManager时,将尝试。。。根据要铺设的对象的特性,根据您的需要合理布局组件 因此,我认为最好是尝试创建一个Border实例并将其设置到JButton中,而不是尝试调整它周围的所有对象 我看看能不能快点想出办法 编辑: 哎呀,这不是很快,但这里是我搞砸了一个1px的线,这让我很恼火 正如我前面所说的,将布局设置为null并不是最好的方法。更好的方法是创建自定义边框并将其设置为按钮或设置为空边框 代码如下:
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);
}
}
编辑
戴夫·卡佩内托写道:
**Oscar>***不幸的是,一旦您使用UIManager.setLookAndFeelUIManager.getSystemLookAndFeelClassName;,此选项将停止工作,这也是我的核心需求,我希望让它看起来尽可能的本土化*
嗯,我不是想让你工作,但为了回答你的问题,你认为你的问题与裁员经理有关,我说这不是问题所在
也许我应该到此为止,但我的程序员渴望让我继续使用这个示例
我很高兴你终于解决了你的问题
…知道为什么吗
对。这是因为当你将布局管理器设置为null来删除布局管理器时,你是在对计算机说,我将负责所有的布局工作;在使用任何其他LayoutManager时,将尝试。。。根据要铺设的对象的特性,根据您的需要合理布局组件
因此,我认为最好是尝试创建一个Border实例并将其设置到JButton中,而不是尝试调整它周围的所有对象
我看看能不能快点想出办法
编辑:
哎呀,这不是很快,但这里是我搞砸了一个1px的线,这让我很恼火
正如我前面所说的,将布局设置为null并不是最好的方法。更好的方法是创建自定义边框并将其设置为按钮或设置为空边框
代码如下:
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);
}
}
编辑
戴夫·卡佩内托写道:
**Oscar>***不幸的是,一旦您使用UIManager.setLookAndFeelUIManager.getSystemLookAndFeelClassName;,此选项将停止工作,这也是我的核心需求,我希望让它看起来尽可能的本土化*
嗯,我不是想让你工作,但为了回答你的问题,你认为你的问题与裁员经理有关,我说这不是问题所在
也许我应该到此为止,但我的程序员渴望让我继续使用这个示例
我很高兴你终于解决了你的问题 要了解布局管理器的工作原理,请查看我在Sun上写的一篇老文章 它很老了,但它很好地讨论了首选大小和布局嵌套 享受,
-Scott要了解布局管理器的工作原理,请查看我在Sun上写的一篇旧文章 它很老了,但它很好地讨论了首选大小和布局嵌套 享受,
-斯科特你好-谢谢大家的帮助 Dan>正是你对首选布局的评论让我开始工作——添加j0.setPreferredSizenew java.awt.Dimensi on32,32;这就是让它工作所需要的一切 Oscar>不幸的是,一旦您使用UIManager.setLookAndFeelUIManager.getSystemLookAndFeelClassName;,此选项将停止工作,这也是我的核心需求,我希望让它看起来尽可能的本土化 例如,我的XP上有3个按钮,如下所示: 。。。以下是您的XP外观: 。。。不幸的是,这不是同一件事-很抱歉我的要求不够明确:- 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);
}
}
斯科特>我受过教育:-谢谢大家的帮助 Dan>正是你对首选布局的评论让我开始工作——添加j0.setPreferredSizenew java.awt.Dimension32,32;这就是让它工作所需要的一切 Oscar>不幸的是,一旦您使用UIManager.setLookAndFeelUIManager.getSystemLookAndFeelClassName;,此选项将停止工作,这也是我的核心需求,我希望让它看起来尽可能的本土化 例如,我的XP上有3个按钮,如下所示: 。。。以下是您的XP外观: 。。。不幸的是,这不是同一件事-很抱歉我的要求不够明确:- 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);
}
}
斯科特>我受过教育:-谢谢你,爸爸!嗯,差不多了;-按照预期的方式使用布局管理器并不能让我得到我想要的技能。但是添加j0.setPreferredSizenew java.awt.Dimension32,32;在j0.setBounds行解决问题之后。谢谢你这个男人!嗯,差不多了;-按照预期的方式使用布局管理器并不能让我得到我想要的技能。但是添加j0.setPreferredSizenew java.awt.Dimension32,32;在j0.setBounds行解决问题之后。谢谢也许我应该停在那里,瑞莉,瑞莉很高兴你没有停下来-我从你介绍的代码中学到了很多-谢谢:-也许我应该停在那里,瑞莉,瑞莉很高兴你没有停下来-我从你介绍的代码中学到了很多-谢谢:-