【发布时间】:2015-03-14 08:16:05
【问题描述】:
我的目标
我希望我的自定义 Swing 组件 CellLabel extends JLabel 始终绘制某些东西 (X),而某些其他元素 (Y) 只有当它的父级 - (a JPanel 持有 CellLabels 的网格) - 告诉它。 (Y) 的绘制取决于网格中相邻单元格的状态,只有JPanel 可以获取此信息并决定是否以及如何为每个孩子绘制 (Y) @ 987654326@.
我的问题
我怎样才能将绘画行为具体化(到一个带有参数的方法中,该方法允许我描述如何准确地绘画(Y)),以便父母可以决定是否需要CellLabel 孩子画(Y)还是不画?
我的问题
那里的每个 Swing 教程都告诉我应该在创建自定义组件时覆盖 paintComponent 方法;但是,在我的应用程序中,组件无法自行决定是否以及如何绘制 (Y),因为它缺少必要的信息。
我尝试编写一个 CellLabel::paintY(int offset) 方法,一旦它决定了如何以及是否绘制 (Y),我可以从父级调用它:
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
}
}
但是,我似乎无法在约定告诉我覆盖的预定义 paint 方法之外获得 Graphics 上下文。我在 (*) 处得到以下异常(实际尝试使用 g2 绘制时):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at CellLabel.paintY(CellLabel.java:77)
at AutomatonUI.createAndShowGUI(AutomatonUI.java:50)
at AutomatonUI.access$000(AutomatonUI.java:22)
at AutomatonUI$1.run(AutomatonUI.java:29)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我在编写业务逻辑和数字运算方面拥有丰富的经验,但总的来说我对 Swing(和 UI 编程)还很陌生,所以如果我做的事情很糟糕,请原谅(并教育我)错了。
【问题讨论】:
-
你的自定义组件不应该以这种方式依赖于父组件,相反,它应该有一个共享模型,它可以询问有关 UI 状态的问题。然后将为每个标签提供确定状态所需的信息(例如它在网格中的当前 x/y 位置)
-
对于example。
标签: java swing user-interface custom-component