JToolBar 中的 JSeperator 将组件移动到右端

JSeperator in JToolBar moves the components to right end

我正在查看 Oracle 的 JToolBar code 并尝试在该工具栏中添加 JLabels。我通过覆盖鼠标事件为它们模拟了类似按钮的感觉。

在我尝试添加一个 JSeperator 之前它工作正常,因为我想要一条垂直线。我在 3 JLabels 之后添加了一个分隔符,导致其余部分移动到右端,如下所示。

我试过在 JSeparator 代码前后添加 addSeparator(),但还是不行。

代码

import javax.swing.JToolBar;
import javax.swing.JButton;
import javax.swing.ImageIcon;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FilenameFilter;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JSeparator;

public class ToolBarDemo extends JPanel
        implements ActionListener {

    protected JTextArea textArea;
    protected String newline = "\n";
    static final private String PREVIOUS = "previous";
    static final private String UP = "up";
    static final private String NEXT = "next";

    public ToolBarDemo() {
        super(new BorderLayout());

        //Create the toolbar.
        final JToolBar toolBar = new JToolBar("Still draggable");
        toolBar.setBorderPainted(true);

        //Getting only files whose name ending with '_24px.png' 
        File dir = new File("G:\MyImagesFolder");
        File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith("_24px.png");
            }
        });

        int count = 0;
        for (File pngFile : files) {
            // Trying to add 'JSeperator' after third 'JLabel'
            if (count == 3) {
                toolBar.addSeparator();
                JSeparator separator = new JSeparator();
                separator.setOrientation(JSeparator.VERTICAL);

                toolBar.add(separator);
                toolBar.addSeparator();
            }
            count++;
            System.out.println(pngFile.toString());
            toolBar.add(getToolBarIcon(pngFile.toString()));
        }

        //Create the text area used for output.  Request
        //enough space for 5 rows and 30 columns.
        textArea = new JTextArea(5, 30);
        textArea.setEditable(true);
        JScrollPane scrollPane = new JScrollPane(textArea);

        //Lay out the main panel.
        setPreferredSize(new Dimension(450, 130));
        add(toolBar, BorderLayout.PAGE_START);
        add(scrollPane, BorderLayout.CENTER);
        JButton b = new JButton("OK");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (toolBar.isVisible()) {
                    toolBar.setVisible(false);
                } else {
                    toolBar.setVisible(true);
                }
            }
        });
        add(b, BorderLayout.PAGE_END);
    }

    public JLabel getToolBarIcon(String fileName) {
        final JLabel lblToolBarIcon = new JLabel(new ImageIcon(fileName));
        lblToolBarIcon.setToolTipText(fileName);
        lblToolBarIcon.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        lblToolBarIcon.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {

            }

            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("pressed");
                lblToolBarIcon.setBorder(BorderFactory.createLoweredSoftBevelBorder());
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("released");

                lblToolBarIcon.setBorder(BorderFactory.createRaisedSoftBevelBorder());

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("enter");
                lblToolBarIcon.setBorder(BorderFactory.createRaisedSoftBevelBorder());
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("exit");
                lblToolBarIcon.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
            }
        });

        return lblToolBarIcon;
    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        String description = null;

        // Handle each button.
        if (PREVIOUS.equals(cmd)) { //first button clicked
            description = "taken you to the previous <something>.";
        } else if (UP.equals(cmd)) { // second button clicked
            description = "taken you up one level to <something>.";
        } else if (NEXT.equals(cmd)) { // third button clicked
            description = "taken you to the next <something>.";
        }

    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("ToolBarDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Add content to the window.
        frame.add(new ToolBarDemo());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                //Turn off metal's use of bold fonts
                UIManager.put("swing.boldMetal", Boolean.FALSE);
                createAndShowGUI();
            }
        });
    }
}

我应该如何克服这个问题?我的错误是什么?

明确指定 JSeparator 的维度,以便 LayoutManager 知道 Component 的任何大小限制。例如,您可以通过覆盖 getMaximumSize 方法来定义 JSeparator 的最大大小:

JSeparator separator = new JSeparator(){
    @Override
    public Dimension getMaximumSize(){
        return new Dimension(5, 25);
    }
};
separator.setOrientation(JSeparator.VERTICAL);
toolBar.add(separator);
//toolBar.add(separator);
toolBar.addSeparator();

不要使用 add(...) 方法来使用 JSeparator。

JToolbar 有一个方便的方法 addSeparator() 可以将分隔符添加到工具栏。