Как я могу устранить пробел при использовании JButton в качестве ComboBoxEditor в Windows L & F? - PullRequest
1 голос
/ 22 октября 2010

Я пытаюсь использовать JButton в качестве редактора в JComboBox.В Mac OS X это выглядит нормально, но в Windows, использующей внешний вид системы, между редактором JButton и самой кнопкой комбо остался ужасный разрыв:

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 ]

2 голосов
/ 22 октября 2010

По какой-то причине Window 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.*;
0 голосов
/ 22 октября 2010

Я думаю, что если вы измените место расположения BorderLayout, к которому вы добавляете, на CENTER, как это:

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

Это решит эту проблему. Хотя кнопка может стать немного больше, но вы можете решить эту проблему, перенастроив значения размера при необходимости.

...