This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Subclassing Swing in Kawa
- From: Nigel Dolby <nigel_dolby at acm dot org>
- To: kawa at sources dot redhat dot com
- Date: Fri, 28 Apr 2006 09:03:12 -0500
- Subject: Subclassing Swing in Kawa
I have experienced a problem in trying to port into Kawa a fairly simple
example of creating a subclass of a Java Swing Interface. The example is
taken from "The Definitive Guide to Java Swing" by John Zukowski pp 93/4
(the original code is given below). This code is supposed to create and
render a diamond-shaped icon; so it has various Constructors to make
diamonds of different sizes and colors, and a paintIcon method that
renders the resulting diamond. Following the Java code I give my attempt
at translating this code into Kawa, which appears to run but doesn't
actually render any diamond. It appears that the reason for this is that
the vertices of the diamond are all zero (which doesn't make for a great
display). The initPolygon method creates a reasonable diamond if it is
run as a function, but I have been unable to get non-zero vertices if I
run it as a method. Can anybody tell me why and what to do about it?
Also, I have occasionally needed to be able to invoke a method on a
super-object when coding a sub-class; is there a way to reference that
in Kawa? Thanks.
Nigel Dolby.
------------------------------------- Swing Code
--------------------------------
import javax.swing.*;
import java.awt.*;
public class DiamondIcon implements Icon {
private Color color;
private boolean selected;
private int width;
private int height;
private Polygon poly;
private static final int DEFAULT_WIDTH = 10;
private static final int DEFAULT_HEIGHT = 10;
public DiamondIcon(Color color) {
this(color, true, DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
public DiamondIcon(Color color, boolean selected) {
this(color, selected, DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
public DiamondIcon(Color color, boolean selected, int width, int height) {
this.color = color;
this.selected = selected;
this.width = width;
this.height = height;
initPolygon();
}
private void initPolygon() {
poly = new Polygon();
int halfWidth = width/2;
int halfHeight = height/2;
poly.addPoint(0, halfHeight);
poly.addPoint(halfWidth, 0);
poly.addPoint(width, halfHeight);
poly.addPoint(halfWidth, height);
}
public int getIconHeight() {
return height;
}
public int getIconWidth() {
return width;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(color);
g.translate(x, y);
if (selected) {
g.fillPolygon(poly);
} else {
g.drawPolygon(poly);
}
g.translate(-x, -y);
}
}
----------------------------------- Kawa Code
---------------------------------
(define-simple-class <DiamondIcon> (<javax.swing.Icon>)
(color type: <java.awt.Color> init-value: (static-field
<java.awt.Color> 'black))
(selected type: <boolean> init-value: #f)
(width type: <int> init-value: 10)
(height type: <int> init-value: 10)
(poly type: <java.awt.Polygon> init-value: (make 'java.awt.Polygon))
(DEFAULT_WIDTH type: <int> init-value: 10)
(DEFAULT_HEIGHT type: <int> init-value: 10)
((DiamondIcon (color :: <java.awt.Color>)) :: <DiamondIcon>
(invoke (this) color #t DEFAULT_WIDTH DEFAULT_HEIGHT))
((DiamondIcon (color :: <java.awt.Color>) (selected :: <boolean>)) ::
<DiamondIcon>
(invoke (this) color selected DEFAULT_WIDTH DEFAULT_HEIGHT))
((DiamondIcon (color :: <java.awt.Color>) (selected :: <boolean>)
(width :: <int>) (height :: <int>)) :: <DiamondIcon>
(slot-set! (this) 'color color)
(slot-set! (this) 'selected selected)
(slot-set! (this) 'width width)
(slot-set! (this) 'height height)
(invoke (this) 'initPolygon))
((initPolygon) :: <void>
(let* ((halfWidth :: <int> (/ (slot-ref (this) 'width) 2))
(halfHeight :: <int> (/ (slot-ref (this) 'height) 2))
(poly (make 'java.awt.Polygon))
)
(invoke poly 'addPoint 0 halfHeight)
(invoke poly 'addPoint halfWidth 0)
(invoke poly 'addPoint (slot-ref (this) 'width) halfHeight)
(invoke poly 'addPoint halfWidth (slot-ref (this) 'height))
(slot-set! (this) 'poly poly)))
((getIconHeight) :: <int>
(slot-ref (this) 'height))
((getIconWidth) :: <int>
(slot-ref (this) 'width))
((paintIcon (c :: <java.awt.Component>) (g :: <java.awt.Graphics>) (x
:: <int>) (y :: <int>))
:: <void>
(invoke g 'setColor (slot-ref (this) 'color))
(invoke g 'translate x y)
(if (slot-ref (this) 'selected)
(invoke g 'fillPolygon (slot-ref (this) 'poly))
(invoke g 'drawPolygon (slot-ref (this) 'poly)))
(format #t "~%Painted ~a in ~a" (slot-ref (this) 'poly) (slot-ref
(this) 'color))
(invoke g 'translate (- x) (- y))))
---------------------------------- Kawa Driver and function calls
------------------------
In Kawa, load this code and execute the (set! *DI* call, then invoke
(LabelSample).
This should bring up a Swing window containing a JLabel in which one
would hope to see a diamond.
Executing the (set! *P* call allows a form such as (slot-ref *P*
'npoints) or (slot-ref *P* 'xpoints) to be evaluated to see what the
diamond actually looks like.
(define-simple-class <ARunnable> (<java.lang.Runnable>)
((run) <void>
(let ((frame (make <javax.swing.JFrame> "Label Sample"))
(label (make <javax.swing.JLabel> (as <javax.swing.Icon> *DI*)))
)
(invoke frame 'add label)
(invoke frame 'setSize 300 100)
(invoke frame 'setVisible #t)
)))
(define LabelSample
(lambda ()
(let ((runner (make <ARunnable>)))
(invoke-static <java.awt.EventQueue> 'invokeLater runner))))
#| (set! *DI* (make 'DiamondIcon
color: (static-field <java.awt.Color> 'red)
selected: #t width: 24 height: 24))
(set! *P* (slot-ref *DI* 'poly)) |#