Java JComboBox Placeholder



好日子

目前,我正在用GUI NetBeans开发一个java桌面应用程序,每次我意识到使用它会适得其反时,我都是新的,我的应用程序有一个形式,其中有几个组合框,我想在其中实现占位符效果。

我想实现的目标示例:

*Country
Germany
Brazil
Japan
United States

我想要";国家;出现在组合框中,但不可选择,从而实现占位符效果,但我不知道如何做到这一点。

目前我所拥有的是标题";国家;在组合框的索引0中,我根本不喜欢它是一个可选选项,此时我用cmbo_country.setForeground(Color.gray);启动组合框以模拟占位符效果。

然后,当组合框的选择改变索引0〃时;国家;将颜色更改为白色并删除索引0。

cmbo_country.setForeground(Color.WHITE);
cmbo_country.removeItemAt(0);

但这是一个非常糟糕的解决方案。

你能帮我做这个吗?

当我阅读的时候,我看到了使用负索引(-1)的可能性,我可以默认选择它,而不在选择中显示,但我不能这样做,因为我会立即出现错误。

cmbo_country.insertItemAt("Country", -1);

错误:Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException

我还没有得到任何方法来增加限制,以便允许指数(-1),我不知道这是否是最好的解决方案,但我感谢你能给我的帮助。

提前谢谢。

升级

测试类:PromptComboBoxRenderer

正如我所说的,我正在使用netbeans GUI

public class Jframe extends javax.swing.JFrame {
public Jframe() {
initComponents();

setTitle("CMBO Prueba");
setSize(600,400);
setResizable(false);
setLocationRelativeTo(null);

jComboBox1.removeAllItems();        
jComboBox1.addItem("Germany");
jComboBox1.addItem("Brazil");
jComboBox1.addItem("Japan");
jComboBox1.addItem("United States");

}
.
.
.
}

到目前为止,我有我的标准组合框:

【样本】【1】

[显示组合框打开][2]

现在应用类别PromptComboBoxRenderer

public class Jframe extends javax.swing.JFrame {

public Jframe() {
initComponents();

setTitle("CMBO Prueba");
setSize(600,400);
setResizable(false);
setLocationRelativeTo(null);

jComboBox1.removeAllItems();        
jComboBox1.addItem("Germany");
jComboBox1.addItem("Brazil");
jComboBox1.addItem("Japan");
jComboBox1.addItem("United States");

jComboBox1.setSelectedIndex(-1);

jComboBox1.setRenderer(new PromptComboBoxRenderer("Country"));
}
.
.
.
}

到目前为止,的结果似乎是正确的

【应用经典样本】[3]

当打开组合框时会出现问题,它已经完全失去了颜色,类似于函数jComboBox1.setEnabled(false);,选择的颜色也会丢失。

【无颜色选择样本】[4]

我试着用以下方式自己应用选择颜色:

public class Jframe extends javax.swing.JFrame {

/**
* Creates new form Jframe
*/
public Jframe() {
initComponents();

setTitle("CMBO Prueba");
setSize(600,400);
setResizable(false);
setLocationRelativeTo(null);

jComboBox1.removeAllItems();        
jComboBox1.addItem("Germany");
jComboBox1.addItem("Brazil");
jComboBox1.addItem("Japan");
jComboBox1.addItem("United States");

jComboBox1.setSelectedIndex(-1);

jComboBox1.setRenderer(new PromptComboBoxRenderer("Country"));


jComboBox1.setRenderer(new DefaultListCellRenderer() {
public void paintCurrentValueBackground(Graphics g,
Rectangle bounds,
boolean hasFocus)
{
g.setColor( Color.RED );            
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
});

}
.
.
.
}

这对我来说也不起作用,首先占位符效果丢失,组合框为空

[样本][5]

尽管现在如果我获得了选择,它并没有被涂成例子中的颜色,在这种情况下是红色的。

【带颜色的选择样本】[6]

提前感谢你能为我提供的所有帮助,并为这个新手感到抱歉。

添加

我加入了以下功能来更改L&F看看我得到了什么:

public void ChangeFormat(){

try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(Jframe.class.getName()).log(Level.SEVERE, null, ex);
}

}

结果是,现在问题不在选择上,而在带白色帽子的组合框上。

[显示更改L&F][7]时

当你打开它时,一切似乎都是正确的

[样本][8]

尽管我不想改变L&F的nimbus为我的项目也许这将有助于找到一个解决方案

谢谢你能给我的帮助。

新更新

应用新东西,尝试修改我放置的SynthComboBoxRenderer的扩展,但这对我不起作用,因为我认为它不适合组件,这就是我使用.getRenderer():得到的结果

javax.swing.plaf.synth.SynthComboBoxUI$SynthComboBoxRenderer[ComboBox.listRenderer,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@16514247,flags=8388616,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=Item 4,verticalAlignment=CENTER,verticalTextPosition=CENTER]

我能把它应用到PromptComboBoxRenderer类中吗???非常感谢的帮助

下一次更新

我在一个空白项目中测试了PromptComboBoxRenderer类的原始代码,并验证了它的工作原理没有问题:

package class;
import java.awt.FlowLayout;
import java.awt.Panel;
import javax.swing.JComboBox;
import javax.swing.JFrame;

public class test {

private JComboBox combo;

public static void main(String[] args) {
new test();

}

public test(){

JFrame v=new JFrame("window);
combo = new JComboBox();
combo.addItem("Germany");
combo.addItem("Brazil");
combo.addItem("Japan");
combo.addItem("United States");

v.getContentPane().setLayout(new FlowLayout());  
v.pack();
v.getContentPane().add(combo);
v.setVisible(true);
v.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
v.add(new Panel());
v.setSize(600, 400);
v.setLocationRelativeTo(null);

combo.setSelectedIndex(-1);

combo.setRenderer(new PromptComboBoxRenderer("Country"));
}


}

正如我在使用jframe创建者和使用Nimbus UI时所看到的那样,出现了这个问题。

在这种情况下,我需要能够应用于我的项目,我留下完整的代码和问题,直到实现了什么。


package ventanas;
import clases.PromptComboBoxRenderer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComboBox;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Jframe extends javax.swing.JFrame {
public Jframe() {

initComponents();

setTitle("CMBO Prueba");
setSize(600,400);
setResizable(false);
setLocationRelativeTo(null);

jComboBox1.removeAllItems();

jComboBox1.addItem("Germany");
jComboBox1.addItem("Brazil");
jComboBox1.addItem("Japan");
jComboBox1.addItem("United States");

jComboBox1.setSelectedIndex(-1);

jComboBox1.setRenderer(new PromptComboBoxRenderer("Country"));

}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {
jComboBox1 = new javax.swing.JComboBox<>();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
getContentPane().add(jComboBox1, new org.netbeans.lib.awtextra.AbsoluteConstraints(150, 60, 260, 40));
pack();
}// </editor-fold>                        
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Jframe().setVisible(true);
}
});
}
// Variables declaration - do not modify                     
private javax.swing.JComboBox<String> jComboBox1;
// End of variables declaration                   
}

正如我之前所说,这种方式是我成功应用所需效果以来最接近解决问题的方式,唯一的问题是,当鼠标通过组合框的不同选项时,选择颜色会丢失。出于某种原因,我也无法将其返回选择颜色。打开组合框时,选择的方法似乎是jComboBox1.setEnabled(false);

我已经在上面留下了一张照片

我尝试的另一种方法是:


package ventanas;
import clases.PromptComboBoxRenderer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComboBox;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Jframe extends javax.swing.JFrame {
public Jframe() {

initComponents();

setTitle("CMBO Prueba");
setSize(600,400);
setResizable(false);
setLocationRelativeTo(null);

jComboBox1.removeAllItems();

jComboBox1.addItem("Germany");
jComboBox1.addItem("Brazil");
jComboBox1.addItem("Japan");
jComboBox1.addItem("United States");

jComboBox1.setSelectedIndex(-1);
jComboBox1 = new JComboBox<String>()
{
@Override
public Object getSelectedItem()
{
Object selected = super.getSelectedItem();
if (selected == null)
selected = "Country";
return selected;
}
};

}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {
jComboBox1 = new javax.swing.JComboBox<>();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
getContentPane().add(jComboBox1, new org.netbeans.lib.awtextra.AbsoluteConstraints(150, 60, 260, 40));
pack();
}// </editor-fold>                        
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Jframe.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Jframe().setVisible(true);
}
});
}
// Variables declaration - do not modify                     
private javax.swing.JComboBox<String> jComboBox1;
// End of variables declaration                   
}

我希望你能帮我解决这个问题,提前感谢

我想要单词"国家;出现在组合框中但不可选择,从而实现占位符效果

您可以为组合框使用自定义渲染器来实现此效果:

class PromptComboBoxRenderer extends BasicComboBoxRenderer
{
private String prompt;
/*
*  Set the text to display when no item has been selected.
*/
public PromptComboBoxRenderer(String prompt)
{
this.prompt = prompt;
}
/*
*  Custom rendering to display the prompt text when no item is selected
*/
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value == null)
setText( prompt );
return this;
}
}

当未选择任何值时,渲染器将显示提示。

创建组合框时,会选择组合框中的第一个项目,因此您需要使用清除选择

comboBox.setSelectedIndex(-1);

有关完整信息,请参阅组合框提示。

替代方法:

有些外观和感觉(如Nimbus)不使用BasicComboBoxRenderer,因此可能更难扩展默认渲染器来显示提示文本。

在这种情况下,您可以覆盖getSelectedItem()方法以获得相同的效果:

comboBox = new JComboBox<String>( ... )
{
@Override
public Object getSelectedItem()
{
Object selected = super.getSelectedItem();
if (selected == null)
selected = "Country";
return selected;
}
};

相关内容

  • 没有找到相关文章

最新更新