... есть идеи почему?
Да. Это происходит потому, что когда вы удаляете менеджер раскладки (устанавливая его на ноль), вы говорите компьютеру: «Я приму все работы по укладке»; при использовании любого другого LayoutManager попытается ... хорошо расположить ваши компоненты в соответствии с вашими потребностями (в зависимости от свойств объектов, которые будут уложены)
Итак, я думаю, что было бы гораздо лучше вместо этого попытаться создать экземпляр Border и установить его в JButton, а не пытаться настроить все объекты вокруг него.
Я посмотрю, смогу ли я придумать что-нибудь быстро.
EDIT:
Упс, это было не так быстро, но вот оно (я испортил линию 1px, которая меня раздражала)
альтернативный текст 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, и я сказал, что это не проблема.
Возможно, мне следовало остановиться на этом, но мой «программистский» зуд заставил меня продолжить выборку. :)
Я рад, что вы решили свою проблему в конце;)