This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)) |#


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]