当为的JComboBox使用setEditable()对准复位当为、JComboBox、setEditable

由网友(流晚涵相怼怨)分享简介:class RuleComboBox extends JComboBox {public RuleComboBox() {super();this.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"abc", "defg"}));((JLabel)...
class RuleComboBox extends JComboBox {

    public RuleComboBox() {
        super();
        this.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"abc", "defg"}));
        ((JLabel) this.getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);
    }

}

getRenderer()行对齐文本中心。

The getRenderer() line aligns the text to centre.

当我使用 ruleComboBox1.setEnabled(假) ruleComboBox1.setEditable(真),文本对齐回而我不想离开了。我怎样才能停止?

When I useruleComboBox1.setEnabled(false) and ruleComboBox1.setEditable(true), the text aligns back to the left which I don't want. How can I stop this?

我要解释一下,我用 setEditable(真)保留组合框中的文本的外观当我将其禁用。

I should explain that I'm using setEditable(true) to keep the appearance of the text within the ComboBox when I disable it.

推荐答案

该编辑器为的JComboBox 必须实现 ComboBoxEditor 接口。默认实现从 BasicComboBoxEditor 返回一个JTextField作为编辑器延伸。 A 的JTextField 不支持显示文本为中心的理念。

The editor for a JComboBox must implement the ComboBoxEditor interface. The default implementation extends from BasicComboBoxEditor which returns a JTextField as the editor. A JTextField doesn't support the concept of displaying text centered.

所以,你可以实现自己的 ComboBoxEditor 。我建议你​​可以使用 BasicComboBoxEditor ,改变code创建一个的JTextPane 而不是的JTextField 。然后,当你创建的文本窗格中,您可以使用:

So you can implement your own ComboBoxEditor. I would suggest you can just use the BasicComboBoxEditor and change the code to create a JTextPane instead of a JTextField. Then when you create the text pane you can use:

SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
StyledDocument doc = textPane.getStyledDocument();
doc.setParagraphAttributes(0, doc.getLength(), center, false);

,这将导致code键为中心

which will cause the code to be centered.

请注意:这不会是一个简单的转换。一个JTextField调用一个的ActionListener 输入键pssed $ P $。 JTextPane中不支持此功能(默认是插入一个新行),所以你将需要复制这个功能对于JTextPane的。这就是你需要使用键绑定办理输入键。所以,你需要包装在一个自定义的动作的ActionListener的,然后绑定Enter键到文本窗格中。

Note: this will not be a straight forward conversion. A JTextField invokes an ActionListener when the Enter key is pressed. A JTextPane doesn't support this functionality (the default is to insert a new line) so you will need to replicate this functionality for the JTextPane. That is you will need to use Key Bindings to handle the Enter key. So you will need to wrap the ActionListener in a custom Action and then bind the Enter key to the text pane.

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.border.Border;
import java.awt.Component;
import java.awt.event.*;

import java.lang.reflect.Method;
//import sun.reflect.misc.MethodUtil;

/**
 * A custom editor for editable combo boxes. The editor is implemented as a JTextPane.
 *
 */
public class TextPaneComboBoxEditor implements ComboBoxEditor {
    protected JTextPane editor;
    private Object oldValue;

    public TextPaneComboBoxEditor() {
        editor = createEditorComponent();
    }

    public Component getEditorComponent() {
        return editor;
    }

    /**
     * Creates the internal editor component. Override this to provide
     * a custom implementation.
     *
     * @return a new editor component
     * @since 1.6
     */
    protected JTextPane createEditorComponent() {
        JTextPane editor = new BorderlessTextPane("",9);
        editor.setBorder(null);

        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        StyledDocument doc = editor.getStyledDocument();
        doc.setParagraphAttributes(0, doc.getLength(), center, false);

        return editor;
    }

    /**
     * Sets the item that should be edited.
     *
     * @param anObject the displayed value of the editor
     */
    public void setItem(Object anObject) {
        String text;

        if ( anObject != null )  {
            text = anObject.toString();
            if (text == null) {
                text = "";
            }
            oldValue = anObject;
        } else {
            text = "";
        }

        // workaround for 4530952
        if (! text.equals(editor.getText())) {
            editor.setText(text);
        }

    }

    public Object getItem() {
        Object newValue = editor.getText();

        // This code only works for Strings. The default implementation would
        // use reflection to create Object of whatever class was stored in the
        // ComboBoxModel. You will need to fix the reflection code if you want
        // to support other types of data in the model

/*
        if (oldValue != null && !(oldValue instanceof String))  {
            // The original value is not a string. Should return the value in it's
            // original type.
            if (newValue.equals(oldValue.toString()))  {
                return oldValue;
            } else {
                // Must take the value from the editor and get the value and cast it to the new type.
                Class<?> cls = oldValue.getClass();
                try {
                    Method method = MethodUtil.getMethod(cls, "valueOf", new Class[]{String.class});
                    newValue = MethodUtil.invoke(method, oldValue, new Object[] { editor.getText()});
                } catch (Exception ex) {
                    // Fail silently and return the newValue (a String object)
                }
            }
        }
*/
        return newValue;
    }

    public void selectAll() {
        editor.selectAll();
        editor.requestFocus();
    }

    public void addActionListener(ActionListener l) {
//        editor.addActionListener(l);

        Action enter = new WrappedActionListener(l);
        editor.getActionMap().put("insert-break", enter);
    }

    public void removeActionListener(ActionListener l) {
//        editor.removeActionListener(l);
    }

    static class BorderlessTextPane extends JTextPane {
        public BorderlessTextPane(String value,int n) {
//            super(value,n);
            setText(value);
        }

        // workaround for 4530952
        public void setText(String s) {
            if (getText().equals(s)) {
                return;
            }
            super.setText(s);
        }

        public void setBorder(Border b) {
            if (!(b instanceof UIResource)) {
                super.setBorder(b);
            }
        }
    }

    /**
     * A subclass of TextPaneComboBoxEditor that implements UIResource.
     * TextPaneComboBoxEditor doesn't implement UIResource
     * directly so that applications can safely override the
     * cellRenderer property with TextPaneListCellRenderer subclasses.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans&trade;
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    public static class UIResource extends TextPaneComboBoxEditor
    implements javax.swing.plaf.UIResource {
    }

    static class WrappedActionListener extends AbstractAction
    {
        private ActionListener listener;

        public WrappedActionListener(ActionListener listener)
        {
            this.listener = listener;
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            listener.actionPerformed(e);
        }
    }
}

所有你需要在你目前的code是:

All you need in your current code is:

comboBox.setEditor( new TextPaneComboBoxEditor() );
阅读全文

相关推荐

最新文章