【问题标题】:Click Event In One JPanel That Updates Another JPanel一个 JPanel 中的单击事件会更新另一个 JPanel
【发布时间】:2012-11-26 04:41:17
【问题描述】:

我有 2 个JPanels,每个都有自己的扩展Jpanel 的类,每个都在jDialog 中。我在其中一个类中放置了一个点击事件,然后在点击发生的位置获取颜色。现在我如何告诉第二个JPanel 重新绘制自己?

我的 jDialog 中的构造函数:

public ColorPickerDialog(java.awt.Frame parent, boolean modal){
    super(parent, modal);
    initComponents();

    cpp = new ColorPicker();
    cpp.setBounds(5, 5, 300, 300);
    cpp.setVisible(true);
    cpp.setOpaque(true);
    cpp.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    add(cpp);

    // Click event is in this class:
    ColorSlider colorSlide = new ColorSlider();
    colorSlide.setBounds(315, 5, 20, 300);
    colorSlide.setVisible(true);
    colorSlide.setOpaque(true);
    colorSlide.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    add(colorSlide);
}

我的点击事件:

public void mouseClick(MouseEvent evt){
    Point pt = evt.getPoint();

    BufferedImage img = (BufferedImage)this.createImage(getWidth(), getHeight());
    int[] colors = new int[3];
    img.getRaster().getPixel(evt.getX(), evt.getY(), colors);
    ColorPickerDialog.sldColor = new Color(colors[0], colors[1], colors[2]);
}

【问题讨论】:

  • 您可以找到共同祖先并指示它重新绘制。 getParent().invalidate(), getParent().repaint()
  • @DavidKroukamp Old school ;) revalidate 是一个更好的选择。关键是通过将父容器(及其子容器)标记为“无效”来尝试强制重绘
  • @MadProgrammer +1 我明白了,只是想知道,所以通过将组件标记为 invalidate() 以希望 repaint() 会尽快被调用?
  • @DavidKroukamp 这就是想法。我们想要“使”父级“无效”,以便它尝试重新绘制它的子级(在本例中是两个组件)。否则重绘管理器可能会决定不需要更新任何内容并忽略重绘请求
  • @DavidKroukamp 在大多数情况下,我认为repaint 可能会起作用,考虑到每秒的请求数,重绘管理器不太可能忽略它们。重新验证组件层次结构可能是一项耗时的操作,实际上可能会减慢重绘周期。在更新频率较低的环境中,重绘管理器可能需要轻推;)。 PS - 好问题;)

标签: java swing


【解决方案1】:

其中一个 JPanel 可以是 Observer,另一个可以是 Observable。然后,当您需要更新时,您只需调用:

setChanged();
notifyObservers();

在您的 Observable JPanel 中。

【讨论】:

  • +1 为清楚起见,虽然这两个类有点古怪,不如here 提到的替代品安全或灵活。
  • 简单的重绘似乎需要做很多工作,但 +1 不错的方法
【解决方案2】:

为您的项目使用工厂模式。当您创建或启动第二个JPanel 时,将其添加到包含对象实例的工厂。进入mouseClick,从工厂调用您的第二个面板并实施:panel.repaint();

一些例子:

 public void mouseClick(MouseEvent evt){
....
 SecondPanel panel = PanelFactory.loadPanel(2);

    panel.revalidate();
    panel.repaint();    
    ....

}




public class PanelFactory{

  private static PanelFactory instance = new PanelFactory();  

  private JPanel mSomePanel = null;

  public static void storePanel(JPanel panel){
     instance.mSomePanel = panel;
  }

   public static JPanel loadPanel(int index){
     ......
     return instance.mSomePanel;

    }
}

【讨论】:

  • 只需调用revalidate() 代替invalidate()validate()。看我的回答here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
相关资源
最近更新 更多