1

JComboBox 内で JButton をエディタとして使用しようとしています。Mac OS X では問題ないように見えますが、システムのルック アンド フィールを使用する Windows では、JButton エディタとコンボ ボタン自体の間に醜いギャップが残っています。

JButton とコンボ ボタンの間のギャップを示す画像

これは、ダイアログを生成するために使用されるテスト コードです。

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

    }
}
4

2 に答える 2

2

何らかの理由で、ウィンドウ 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 調整の前後でエディターの幅がどのように変化するかを示す出力を追加しました。また、XPStyle クラスは公開されていないため、XP LAF を確認する方法もわかりません。

LAF のインポート:

import javax.swing.plaf.basic.*;
import com.sun.java.swing.plaf.windows.*;
于 2010-10-22T05:29:29.507 に答える
0

次のように、追加するBorderLayoutの場所をCENTERに変更すると思います:

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

その問題を解決してくれます。ボタンが少し大きくなる可能性がありますが、必要に応じてサイズの値を再調整することで解決できます。

于 2010-10-22T02:06:42.643 に答える