将自定义Swing组件的绘制委托给父级

时间:2015-01-15 19:53:49

标签: java swing user-interface custom-component

我的目标

我希望我的自定义Swing组件CellLabel extends JLabel始终绘制某些内容(X),以及某些其他元素(Y)仅在其父级 - (JPanel持有网格{ {1}} s ) - 告诉它。 (Y)的绘制取决于网格中相邻单元格的状态,只有CellLabel可以获取此信息并决定是否应为每个绘制(Y)孩子JPanel

我的问题

我如何外化(进入一个方法,允许我描述如何完全绘制(Y))绘画行为,以便父母可以决定是否需要{{1}孩子画(Y)与否?

我的问题

每个Swing教程告诉我在创建自定义组件时应该覆盖CellLabel方法;但是,在我的应用程序中,组件无法自行决定是否应该绘制(Y),因为它缺少必要的信息。

我尝试编写一个CellLabel方法,一旦决定了如何绘制(Y),就可以从父方调用:

paintComponent

但是,似乎我无法控制常规告诉我覆盖的预定义CellLabel::paintY(int offset)方法之外的class CellLabel extends JLabel { void paintComponent(Graphics g) { super.paintComponent(g); // Paint elements (X) which should always be painted, independent // of external state } void paintY(int[] params){ Graphics2D g2 = (Graphics2D) this.getGraphics(); // Perform some calculation with params that decide how painting is done // (*) Actually paint elements (Y) by using the g2 graphics context } } 上下文。我在(*)得到以下异常(当实际尝试用g2绘画时):

Graphics

我有丰富的编码业务逻辑和数字运算的经验,但我对Swing(和UI编程)一般都是新手,所以请原谅我(并教育我)如果我正在做一些可怕的事情错。

2 个答案:

答案 0 :(得分:2)

更好的方法可能是将您的逻辑与Swing GUI库分开。例如,定义包含CellContainer个对象的Cell类,可以在每次渲染之前更新(在更新中,您可以从Cell更新CellContainer但是您希望)。然后,您可以使用CellContainerPanelCellLabel类来扩展相应的Swing类,每个类引用CellContainerCell,这些类只会绘制其引用可用的状态

答案 1 :(得分:0)

IIRC,你的paintComponent函数需要调用super.paintComponent(g);

我最后一次使用swing编写程序时,我在一个类中声明了一个静态图形对象,一切都可以访问(这可能是一个可怕的事情,但它是一个解决方法,帮助我完成我的任务)。而不是将信息存储在二维数组中,存储"信息"数组中的对象。那些信息对象(例如,对象x)可以包含关于单元本身的所有信息,以及" draw(g)"方法。该绘制方法可以决定如何绘制该单元格。在paintComponent函数中,您现在可以调用

//where g is the graphics object
for (array x : array of arrays) {
    for (informationObject y : x) {
        y.draw(g);
    }
}

现在,您可以在对象内部进行所有计算,而不必处理获取外部信息和在外部进行计算。 (然后,代码也将更容易调试)