JTextField в JToolbar - не может правильно отображаться как в Linux, так и в Windows
Пожалуйста, смотрите SSCCE ниже:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
@SuppressWarnings("serial")
public class GlueTest extends JComponent {
private JFrame frame;
private JToolBar toolbar;
private JLabel label_1;
private JTextField textField_1;
private JLabel label_2;
private JTextField textField_2;
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GlueTest window = new GlueTest();
window.frame.setVisible(true);
window.frame.requestFocusInWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public GlueTest() {
initialize();
}
private void initialize() {
frame = new JFrame("Test");
frame.setBounds(0,0,800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
toolbar.setMaximumSize(new Dimension(frame.getWidth(), frame.getHeight()));
frame.getContentPane().add(toolbar, BorderLayout.NORTH);
Component horizontalGlue = Box.createHorizontalGlue();
toolbar.add(horizontalGlue);
label_1 = new JLabel(" 1 ");
toolbar.add(label_1);
textField_1 = new JTextField();
textField_1.setColumns(9);
textField_1.setMaximumSize(textField_1.getPreferredSize());
toolbar.add(textField_1);
label_2 = new JLabel(" 2 ");
toolbar.add(label_2);
textField_2 = new JTextField();
textField_2.setColumns(9);
textField_2.setMaximumSize(textField_2.getPreferredSize());
toolbar.add(textField_2);
}
}
Обратите внимание, что я использую "системный" внешний вид. В Windows 7 он отображается отлично. Размер текстовых полей автоматически увеличивается до максимального размера, а горизонтальный клей слева увеличивается настолько, насколько это возможно, вынуждая их выравнивать по правому краю.
Тем не менее, в Linux (Ubuntu 12.04, если это имеет значение), это в конечном итоге отличается. Текстовые поля прокручиваются прямо с фрейма! Горизонтальные размеры клея сами по себе слишком велики.
Я попробовал несколько других способов заставить его правильно отображаться в обоих случаях, но не повезло. Фактически, единственный способ заставить его правильно отображаться в Linux - это удалить все стили текстового поля (максимальная ширина, столбцы и т. Д.), И тогда ему удастся не прокрутить рамку, но это бесполезно, так как имеет всего несколько пикселей ширины.
Как заметка, у меня даже не было возможности попробовать Mac OS, но мне было бы любопытно, как это получится.
2 ответа
Вопрос (не *** пользователь nix), у вас есть такая же проблема с этим кодом
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.border.EtchedBorder;
@SuppressWarnings("serial")
public class GlueTest extends JComponent {
private JFrame frame;
private JToolBar toolbar;
private JLabel label_1;
private JTextField textField_1;
private JLabel label_2;
private JTextField textField_2;
public GlueTest() {
toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
toolbar.setAlignmentY(TOP_ALIGNMENT);
toolbar.add(Box.createHorizontalGlue());
label_1 = new JLabel(" 1 ");
toolbar.add(label_1);
toolbar.add(Box.createRigidArea(new Dimension(10,1)));
textField_1 = new JTextField();
textField_1.setColumns(9);
textField_1.setMaximumSize(textField_1.getPreferredSize());
toolbar.add(textField_1);
toolbar.add(Box.createHorizontalStrut(10));
label_2 = new JLabel(" 2 ");
toolbar.add(label_2);
toolbar.add(Box.createRigidArea(new Dimension(10,1)));
textField_2 = new JTextField();
textField_2.setColumns(9);
textField_2.setMaximumSize(textField_2.getPreferredSize());
toolbar.add(textField_2);
toolbar.add(Box.createHorizontalStrut(10));
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(toolbar, BorderLayout.NORTH);
frame.add(new JTextArea(10, 40));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
GlueTest window = new GlueTest();
}
});
}
}
переключите встроенный BoxLayout в BorderLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.border.EtchedBorder;
@SuppressWarnings("serial")
public class GlueTest extends JComponent {
private JFrame frame;
private JToolBar toolbar;
private JLabel label_1;
private JTextField textField_1;
private JLabel label_2;
private JTextField textField_2;
public GlueTest() {
toolbar = new JToolBar();
toolbar.setFloatable(false);
toolbar.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
toolbar.setLayout(new BorderLayout(10, 10));
JPanel panel = new JPanel();
panel.setOpaque(false);
label_1 = new JLabel("1");
panel.add(label_1);
textField_1 = new JTextField();
textField_1.setColumns(9);
panel.add(textField_1);
label_2 = new JLabel("2");
panel.add(label_2);
textField_2 = new JTextField();
textField_2.setColumns(9);
panel.add(textField_2);
toolbar.add(panel, BorderLayout.EAST);
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(toolbar, BorderLayout.NORTH);
frame.add(new JTextArea(10, 40));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
GlueTest window = new GlueTest();
}
});
}
}
В качестве альтернативы рассмотрите возможность изменения JToolBar
макет для FlowLayout.RIGHT
,
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.border.EtchedBorder;
public class Test extends JComponent {
public Test() {
JToolBar toolbar = new JToolBar();
toolbar.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
toolbar.setLayout(new FlowLayout(FlowLayout.RIGHT));
toolbar.add(new JLabel("1"));
toolbar.add(new JTextField(9));
toolbar.add(new JLabel("2"));
toolbar.add(new JTextField(9));
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(toolbar, BorderLayout.NORTH);
frame.add(new JTextArea(10, 40));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Test window = new Test();
}
});
}
}