gpt4 book ai didi

java - 对 JComboBox 使用 setEditable() 时对齐会重置

转载 作者:行者123 更新时间:2023-12-01 11:16:22 29 4
gpt4 key购买 nike

class RuleComboBox extends JComboBox {

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

}

getRenderer() 行将文本居中对齐。

当我使用ruleComboBox1.setEnabled(false)ruleComboBox1.setEditable(true)时,文本会向左对齐,这是我不想要的。我怎样才能阻止这个?

我应该解释一下,当我禁用它时,我使用 setEditable(true) 来保持 ComboBox 中文本的外观。

最佳答案

JComboBox 的编辑器必须实现 ComboBoxEditor 接口(interface)。默认实现扩展自 BasicComboBoxEditor,它返回一个 JTextField 作为编辑器。 JTextField 不支持居中显示文本的概念。

因此您可以实现自己的ComboBoxEditor。我建议您只需使用 BasicComboBoxEditor 并更改代码以创建 JTextPane 而不是 JTextField。然后,当您创建文本 Pane 时,您可以使用:

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

这将使代码居中。

注意:这不会是直接的转换。当按下 Enter 键时,JTextField 会调用 ActionListener。 JTextPane 不支持此功能(默认设置是插入新行),因此您需要为 JTextPane 复制此功能。也就是说,您需要使用Key Bindings 来处理Enter 键。因此,您需要将 ActionListener 包装在自定义 Action 中,然后将 Enter 键绑定(bind)到文本 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);
}
}
}

当前代码中您需要的是:

comboBox.setEditor( new TextPaneComboBoxEditor() );

关于java - 对 JComboBox 使用 setEditable() 时对齐会重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31786422/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com