JTextField in JToolbar - cannot display properly in both Linux and Windows

五迷三道 提交于 2019-12-10 22:45:31

问题


Please see the SSCCE below:

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);
    }
}

Notice I am using "system" look and feel. In Windows 7, it displays perfectly. The textfields size automatically to their maximum size, and the horizontal glue to their left grows as much as it can, forcing them to be right aligned.

However, in Linux (Ubuntu 12.04 if it matters), it ends up way different. The textfields scroll right off the frame! The horizontal glue sizes itself too large.

I've tried several other different ways to get it to display properly in both, with no luck. In fact, the only way I can get it to display properly in Linux is to remove all the stylings of the textfield (max width, columns, etc), and then it succeeds in not scrolling off the frame, but it is useless since it has only a few pixels of width.

As a sidenote, I haven't even got a chance to try on a Mac OS, but I'd be curious how that turns out.


回答1:


question (not ***nix user), do you have the same issue with this code

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();
            }
        });
    }
}

switch the built_in BoxLayout to 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();
            }
        });
    }
}



回答2:


As an alternative, consider changing the JToolBar layout to 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();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/15472260/jtextfield-in-jtoolbar-cannot-display-properly-in-both-linux-and-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!