【发布时间】:2021-03-04 13:25:24
【问题描述】:
美好的一天
目前我正在使用 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]
虽然我不想为我的项目更改 nimbus 的 L&F 也许这将有助于找到解决方案
感谢您给予我的帮助。
新更新
应用新的东西,尝试修改我放在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
}
正如我之前所说,这种方式是我设法解决问题的最接近的方式,因为成功应用了所需的效果,唯一的问题是当鼠标经过组合框的不同选项时,选择颜色会丢失by 出于某种原因,我也不能把它还给那个选择颜色。似乎打开组合框时,选择有一个方法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
}
希望你能帮我解决这个问题,在此先感谢
【问题讨论】:
-
一种选择是将“国家/地区”放在 JComboBox 旁边或上方的 JLabel 中。
-
1) 这不是minimal reproducible example,因为我无法复制/粘贴/编译和测试。 2) 正如我建议的那样,您没有使用默认的 LAF,因此您的代码使用的渲染器不是 BasicComboBoxRenderer。因此,您应该扩展 LAF 使用的默认渲染器,而不是扩展 BasicComboBoxRenderer。您只需使用组合框的
getRenderer()方法来获取默认渲染器。然后你应该能够添加在我的渲染器中找到的基本逻辑。 -
@camickr 再次感谢您的帮助,抱歉没有提供完整的可执行代码,但这是使用 GUI netbeans 自动创建的,我将考虑尽快从代码开始创建 Jframe,我仍然这样做没有解决问题,但上面很有意义,不,我明白如何修改扩展,我已经更新了我正在尝试的问题,希望你能帮助我的朋友,非常感谢你的所有帮助。
-
javax.swing.plaf.synth.SynthComboBoxUI$SynthComboBoxRenderer - 所以 Nimbus 的默认渲染器是一个内部类。因此无法扩展,因为它将使用我们无权访问的 SynthComboBoxUI 类的实例变量。所以这里建议的方法不适用于 Nimbus LAF。
-
@camickr 我明白了,有没有办法用 nimbus L&F 实现这种效果(占位符),或者如果我发布我的自定义组合框的代码,你能给我最后一个建议如何应用它我正在使用 BasicComboBoxUI ???提前致谢。
标签: java swing jcombobox placeholder