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,

Скриншот Ubuntu

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();
            }
        });
    }
}
Другие вопросы по тегам