我最初在MigLayout论坛上发布了这个问题,因为它是针对特定布局管理器的一些扩展,我会说。不幸的是,现在已经有一周没有任何评论了,所以我想在这里重新发布一个问题,希望它不被认为是X-post。
好吧,我有以下问题: 一般来说,我希望“灰显”某些内容(更准确地说是JPanel的内容)。我几乎设法通过将另一个JPanel“流动”在透明色的所需区域上来达到预期的效果。但是还有一个主要问题: 一旦我将覆盖面板设置为可见,下面的组件将不会立即绘制正确的。相反,它们最初会涂上一些白色,直到例如我最小化并重新最大化框架,这将导致透明效果被绘制正确。
作为例子,我附上了“越野车”外观的屏幕截图。注意单选按钮和复选框的白色外观。另外,我附加了代码来重现效果。目前我正在开发Windows 7,32位Java 1.5。 (Java 1.6没有任何区别)。
我使用各种paint()/ repaint()/(in / re)validate()/ etc玩了很多。方法。在将叠加面板设置为可见后,没有任何方法可以正确绘制叠加面板。
有什么想法吗?
BR,Chris
EDIT1:关于代码示例 - 如果您运行它,则必须单击“检查”按钮以触发覆盖面板。 :)我注意到的另一件事是外观问题因使用的UI L& F而异。在我的情况下,我使用过一次Windows和原生Java用户界面(称为金属?),他们显示了不同的结果,即使它们都没有正常工作:P
链接获取错误的屏幕截图:Screenshot
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
public class MigTest {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestLayeredPane());
f.pack();
f.setVisible(true);
}
public static class TestLayeredPane extends JPanel {
private JPanel pnl_overlay_;
public TestLayeredPane() {
super();
this.setLayout(new MigLayout("fill, wrap 2", "", ""));
initLayout();
}
private void initLayout() {
JPanel pnl_direction = new JPanel(new MigLayout("wrap 3", "", ""));
JPanel pnl_settings = new JPanel(new MigLayout("wrap 1", "", ""));
JPanel pnl_input = new JPanel(new MigLayout("wrap 3", "", ""));
JLabel lbl_ask_for = new JLabel();
JLabel lbl_translation = new JLabel();
ButtonGroup btn_group_ = new ButtonGroup();
JRadioButton radiobtn_ask_lang1_ = new JRadioButton();
JRadioButton radiobtn_ask_lang2_ = new JRadioButton();
JRadioButton radiobtn_ask_random_ = new JRadioButton();
JCheckBox chkbox_loop_ = new JCheckBox();
JCheckBox chkbox_repeat_false_ = new JCheckBox();
JCheckBox chkbox_letter_count_ = new JCheckBox();
JCheckBox chkbox_ask_all_ = new JCheckBox();
JLabel lbl_progress_ = new JLabel();
JLabel lbl_question_ = new JLabel();
JButton btn_check_ = new JButton();
JButton btn_push_back_ = new JButton();
JTextField tfield_answer_ = new JTextField();
/** Customize all elements of our layout **/
lbl_ask_for.setText("Ask for:");
lbl_translation.setText("translation");
radiobtn_ask_lang1_.setText("1st language");
radiobtn_ask_lang2_.setText("2nd language");
radiobtn_ask_random_.setText("Random language");
btn_group_.add(radiobtn_ask_lang1_);
btn_group_.add(radiobtn_ask_lang2_);
btn_group_.add(radiobtn_ask_random_);
chkbox_loop_.setText("Loop");
chkbox_repeat_false_.setText("Repeat false answers");
chkbox_letter_count_.setText("Show letter count");
chkbox_ask_all_.setText("Ask for 1st and 2nd language");
btn_check_.setText("Check");
btn_check_.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
finishTraining();
}
});
btn_push_back_.setText(" Push back");
/** Add all elements to this panel **/
pnl_direction.add(lbl_ask_for, "span 1 3");
pnl_direction.add(radiobtn_ask_lang1_);
pnl_direction.add(lbl_translation, "span 1 3");
pnl_direction.add(radiobtn_ask_lang2_);
pnl_direction.add(radiobtn_ask_random_);
pnl_settings.add(chkbox_loop_);
pnl_settings.add(chkbox_repeat_false_);
pnl_settings.add(chkbox_letter_count_);
pnl_settings.add(chkbox_ask_all_);
pnl_input.add(lbl_question_, "align center");
pnl_input.add(lbl_progress_, "span 2, align center");
pnl_input.add(tfield_answer_, "span 1 2, align center, w 200!");
pnl_input.add(btn_check_, "growy");
pnl_input.add(btn_push_back_);
pnl_overlay_ = new JPanel(new MigLayout("fill", "", ""));
pnl_overlay_.setBackground(new Color(127, 127, 127, 100));
this.add(pnl_overlay_, "pos (0%+2px) (0%+2px) (100%-2px) (100%-2px) ");
pnl_overlay_.setVisible(false);
this.add(pnl_direction, "gapbefore push");
this.add(pnl_settings, "gapafter push");
this.add(pnl_input, "span 2, gapbefore push, gapafter push");
}
private void finishTraining() {
//disable all visible items in the content area
for (Component comp : this.getComponents()) {
if (comp instanceof JPanel) {
for (Component comp2 : ((JPanel) comp).getComponents()) {
comp2.setEnabled(false);
}
}
else {
comp.setEnabled(false);
}
}
pnl_overlay_.setVisible(true);
}
}
}
答案 0 :(得分:1)
在没有尝试调试代码的情况下,我快速搜索了禁用容器及其子代的主题。基本上有两种方法,包括递归迭代子控件并禁用它们或覆盖禁用面板,就像你正在做的那样。
如果您不必跟踪所有子项的先前已启用状态,并且要在重新启用父容器时还原它们,则递归选项很简单。像这样的函数会这样做:
static void setChildrenEnabled(Container root, boolean enable)
{
Component children[] = root.getComponents();
for(int i = 0; i < children.length; i++)
{
children[i].setEnabled(enable);
if(children[i] instanceof Container)
{
setChildrenEnabled((Container) children[i], enable);
}
}
}
对于像你这样的方法,我发现了一个非常好的帖子,其中包含了对陷阱和源代码的正确解释,你可以在这里找到:http://tips4java.wordpress.com/2009/08/02/disabled-panel/
我希望那里有一些有用的东西。