代码之家  ›  专栏  ›  技术社区  ›  Gabriel

在Windows L&F中使用jbutton作为组合框编辑器时,如何消除间隙?

  •  1
  • Gabriel  · 技术社区  · 15 年前

    我试图用jbutton作为jcombobox中的编辑器。在Mac OS X上,这看起来不错,但在使用系统外观的Windows上,jbutton编辑器和组合按钮本身之间还存在一个难看的间隙:

    这是用于生成对话框的测试代码:

    >代码>导入Java.AWT.*; 导入Java.AWT.Engult.*; 导入javax.swing.*; 公共类ButtonEditortest实现可运行{ string[]items=“一”、“二”、“三” 组合框模型; buttonEditortest()。{ //我们的模型,测试时保持简单 model=new-defaultComboBoxModel(items); //在EDT上创建UI swingutilities.invokelater(this); } //在事件调度线程上创建UI @重写 public void run()。{ jComboBox ComboBox=新的jComboBox(模型); ComboBox.setEditable(真); combobox.seteditor(new combobuttoneditor()); jframe frame=new jframe(“jComboBox with jButton编辑器测试”); frame.setDefaultCloseOperation(jframe.exit在关闭时退出); frame.getContentPane().add(组合框,borderlayout.north); 框架。调整尺寸(200,100); frame.setVisible(真); } 公共静态void main(string[]args)引发异常{ string lookandfeelclassname=uimanager.getSystemLookandfeelclassname(); uimanager.setlookandfeel(lookandfeelclassname); 新建按钮editorest(); } 类ComboButtonEditor实现ComboBoxeditor{ private jbutton button=new jbutton(); 私有对象项; @重写 公共void AddActionListener(ActionListener arg0){ //用户界面测试不需要 } @重写 公共组件GetEditorComponent()。{ 返回按钮; } @重写 公共对象getItem()。{ 返回项目; } @重写 public void removeActionListener(actionListener arg0){ //用户界面测试不需要 } @重写 public void selectall()。{ //用户界面测试不需要 } @重写 公共void集合项(对象项){ this.item=项目; button.settext(item.toString()); } } } < /代码>

    image showing gap between JButton and combo button

    这是用于生成对话框的测试代码:

    import java.awt.*;
    import java.awt.event.*;
    
    import javax.swing.*;
    
    
    public class ButtonEditorTest implements Runnable {
    
        String[] items = {"One", "Two", "Three"};
    
        ComboBoxModel model;
    
        ButtonEditorTest() {
            // our model, kept simple for the test
            model = new DefaultComboBoxModel(items);
    
            // create the UI on the EDT
            SwingUtilities.invokeLater(this);
        }
    
        // creates UI on the event dispatch thread
        @Override
        public void run() {
            JComboBox comboBox = new JComboBox(model);
            comboBox.setEditable(true);
            comboBox.setEditor(new ComboButtonEditor());
    
            JFrame frame = new JFrame("JComboBox with JButton editor test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(comboBox, BorderLayout.NORTH);
            frame.setSize(200, 100);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) throws Exception {
            String lookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
            UIManager.setLookAndFeel(lookAndFeelClassName);
            new ButtonEditorTest();
        }
    
    
        class ComboButtonEditor implements ComboBoxEditor {
    
            private JButton button = new JButton();
            private Object item;
    
            @Override
            public void addActionListener(ActionListener arg0) {
                // not needed for UI test
            }
    
            @Override
            public Component getEditorComponent() {
                return button;
            }
    
            @Override
            public Object getItem() {
                return item;
            }
    
            @Override
            public void removeActionListener(ActionListener arg0) {
                // not needed for UI test
            }
    
            @Override
            public void selectAll() {
                // not needed for UI test
            }
    
            @Override
            public void setItem(Object item) {
                this.item = item;
                button.setText(item.toString());
            }
    
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   camickr    15 年前

    出于某种原因,窗口LAF将覆盖按钮的默认布局。这导致按钮变窄。但是,编辑器的宽度并没有增加以解释更窄的按钮,因此会出现间隙。以下是WindowsComboBoxUI中的代码:

    protected LayoutManager createLayoutManager() {
        return new BasicComboBoxUI.ComboBoxLayoutManager() {
        public void layoutContainer(Container parent) {
        super.layoutContainer(parent);
    
        if (XPStyle.getXP() != null && arrowButton != null) {
            Dimension d = parent.getSize();
            Insets insets = getInsets();
            int buttonWidth = arrowButton.getPreferredSize().width;
            arrowButton.setBounds(WindowsGraphicsUtils.isLeftToRight((JComboBox)parent)
          ? (d.width - insets.right - buttonWidth)
          : insets.left,
          insets.top,
          buttonWidth, d.height - insets.top - insets.bottom);
        }
        }
    };
    }
    

    更好的布局可能是:

    comboBox.setUI( new WindowsComboBoxUI()
    {
        @Override
        protected LayoutManager createLayoutManager()
        {
            return new BasicComboBoxUI.ComboBoxLayoutManager()
            {
                public void layoutContainer(Container parent)
                {
                    super.layoutContainer(parent);
    
                    System.out.println(editor.getBounds());
                    System.out.println(arrowButton.getBounds());
    
    //              if (XPStyle.getXP() != null && arrowButton != null)
    //              {
                        Dimension d = parent.getSize();
                        Insets insets = getInsets();
                        int buttonWidth = arrowButton.getPreferredSize().width;
                        boolean isLeftToRight = parent.getComponentOrientation().isLeftToRight();
    
                        arrowButton.setBounds(isLeftToRight
                        ? (d.width - insets.right - buttonWidth)
                        : insets.left, insets.top, buttonWidth, d.height - insets.top - insets.bottom);
    
                        System.out.println(editor.getBounds());
                        System.out.println(arrowButton.getBounds());
    
                        Dimension size = editor.getSize();
                        editor.setSize(arrowButton.getLocation().x - 1, size.height);
    //              }
    
                }
            };
        }
    });
    

    我添加了一些输出来显示在xp调整之前/之后编辑器宽度是如何变化的。另外,我不知道如何检查xp laf,因为xpstyle类不是公共的。

    LAF的进口:

    import javax.swing.plaf.basic.*;
    import com.sun.java.swing.plaf.windows.*;
    
        2
  •  0
  •   Luis Miguel Serrano    15 年前

    我认为,如果更改添加到的边框布局的位置、居中位置,如下所示:

    frame.getContentPane().add(comboBox, BorderLayout.CENTER);
    

    它将解决这个问题。 按钮可能会变大一点,但如果需要,可以通过重新调整大小值来解决这个问题。