UIManager在按钮操作中的作用

3
我有一个LoginScreen和一个MainWindow。当连接尝试成功时,LoginScreen将被disposed并出现MainWindow。
我有一个按钮拥有ActionListener来创建一个JOptionPane。代码实际上已经成功运行。我认为有三个问题在Painting中。让我逐一解释这些问题; 问题1;
UIManager UI=new UIManager();
Object paneBG = UI.get("OptionPane.background");
Object panelBG = UI.get("Panel.background");
UI.put("OptionPane.background", Color.red);
UI.put("Panel.background", Color.red);

String[] buttons2 = { "EXIT", "OK" };
int rc2 = JOptionPane.showOptionDialog(MainWindow.this, 
                                        panel,
                                        "User Input", 
                                        JOptionPane.INFORMATION_MESSAGE,
                                        JOptionPane.PLAIN_MESSAGE, 
                                        icon, 
                                        buttons2, 
                                        buttons2[1]
                                      );

UI.put("OptionPane.background", paneBG);
UI.put("Panel.background", panelBG);

我使用上面的代码来改变 OptionPane 的背景颜色,并将其展示给用户,然后将UI颜色回滚到原始状态。
如果我直接运行 MainWindow 并点击按钮,颜色会改变(确保在OptionPane中,面板和按钮区域保持原始颜色,但其他OptionPane区域会变成红色。这是另一个问题),效果如下;

enter image description here

但是,当我从LoginScreen返回时,登录尝试成功,LoginScreen被关闭,MainWindow出现。我点击同一个按钮,但是OptionPane现在没有被绘制出来,就像这样;

enter image description here

问题2:
在MainWindow中有另一个按钮,它创建了另一个OptionPane。我直接运行MainWindow并点击第一个按钮(改变UI颜色和回滚操作),关闭它,然后点击第二个按钮(其中有另一个OptionPane),但是OptionPane仍然被涂色,所以UI颜色没有回滚到默认值。
问题3:
如果我们解决了第一和第二个问题,我该如何使这些内部面板(其中包含标签和文本字段面板和按钮面板)透明?

如果您重复使用相同的对话框,为什么不创建一个定制的 JDialog - user1803551
因为我需要为JDialog中的每个按钮编写ActionListener。我认为OptionPane很容易使用。实际上,我需要将Gradient Painting应用到OptionPanes中。如果我无法解决这些问题,我会转向JDialog。 - Black White
然后发布一个 MCVE。确保将您的代码复制粘贴到一个新项目中,并在发布之前确保它可以编译和运行。 - user1803551
既然你正在请求“输入”,为什么不使用'showInputDialog'而是使用'showOptionDialog'? - DevilsHnd
1个回答

1

首先,UIManager的公共方法是静态的。创建UIManager的实例是不正确、误导和无意义的。调用这些方法的正确方式是:

UIManager.put("OptionPane.background", Color.red);

其次,您可能不应该使用全局设置来动态更改颜色。相反,通过创建JOptionPane的实际实例而不是使用静态便捷方法来设置所需对象的颜色:

static void setBackground(Component c,
                          Color color) {
    if (c instanceof JTextField || c instanceof AbstractButton) {
        return;
    }

    c.setBackground(color);
    if (c instanceof Container) {
        Component[] children = ((Container) c).getComponents();
        for (Component child : children) {
            setBackground(child, color);
        }
    }
}

int show(Icon icon,
         JComponent panel) {

    String[] buttons2 = { "EXIT", "OK" };
    JOptionPane optionPane = new JOptionPane(panel,
                                             JOptionPane.PLAIN_MESSAGE, 
                                             JOptionPane.DEFAULT_OPTION,
                                             icon, 
                                             buttons2, 
                                             buttons2[1]);
    setBackground(optionPane, Color.RED);

    optionPane.createDialog(MainWindow.this, "User Input").setVisible(true);

    Object value = optionPane.getValue();
    int rc2 = JOptionPane.CLOSED_OPTION;
    if (value instanceof String) {
        rc2 = Arrays.asList(buttons2).indexOf(value);
    }

    return rc2;
}

您需要注意区分消息类型参数和选项类型参数。同时传递INFORMATION_MESSAGE和PLAIN_MESSAGE作为参数是不正确的。文档指出第四个和第五个参数分别是选项类型和消息类型;选项类型参数应该是DEFAULT_OPTION、OK_CANCEL_OPTION、YES_NO_OPTION等。


这个例子非常有教育意义和帮助性。我认为还可以在这个例子中添加一些内容,以便使用GradientPaint来绘制OptionPane。 - Black White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接