javajcombobox占位符

cczfrluj  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(399)

很好的一天
目前我正在用java开发一个带有gui netbeans的桌面应用程序,每次我意识到使用它会产生一些反作用,我在这方面有些新东西,我的应用程序有一个表单,其中有几个组合框,我想在其中实现占位符效果。
我想达到的目标的例子:


* Country

Germany
Brazil
Japan
United States

我想“国家”一词出现在组合框,但不可选择,从而实现占位符的效果,但我不知道如何做到这一点。
目前我拥有的是组合框索引0中的标题“country”,我一点也不喜欢它是一个可选择的选项,现在我用一个 cmbo_country.setForeground(Color.gray); 模拟占位符效果。
然后当选择组合框时,将索引0“country”更改为任何其他颜色,将颜色更改为白色并删除索引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 正如我所说的,我正在使用netbeansgui

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的光轮也许这将有助于找到一个解决方案
谢谢你能给我的帮助。
新的更新
应用新事物,尝试修改我提出的扩展 `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 creator和nimbusui时所看到的那样,问题发生了。
在这种情况下,我需要能够适用于我的项目,我留下完整的代码和问题,直到什么已经实现的时刻。

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                   

}

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

bf1o4zei1#

我想“国家”一词出现在组合框,但不可选择,从而实现占位符的效果
可以使用组合框的自定义渲染器来实现此效果:

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

相关问题