// JP opened flex table

Click to See Complete Forum and Search --> : Swing components don't show until mouse over happens


DrPL
July 23rd, 2008, 06:58 AM
Hi,
I'm trying to write a JApplet, which will show two panels; the leftmost one shows an attribute, subclassed from JPanel, surrounded by arrow buttons. The right most ones shows a series of JButtons and TextFields to display current time, and also to start, stop a playback routine.
However, when I start up the applet, all I get is the "top" button, and the two JTextFields. The central JPanel doesn't show up at all.

I've put some of the code below in case anyone can see whats wrong.

This is the Applet's init method:

public void init()
{

// Code snipped here that initialises variables

// draw GUI

content=getContentPane();

content.setLayout(new FlowLayout());

display = new JPanel();

controls = new JPanel();

initialisegridbaglayout( content );

// All the buttons are subclassed from JButton so that I can
// draw up, down, left, right arrows on them. The class is
// called ButtonManipulator

buttonstart.addActionListener(this);
buttonstop.addActionListener(this);
buttonpause.addActionListener(this);
buttonresetcanvas.addActionListener(this);

controls.setLayout(new BoxLayout( controls, BoxLayout.Y_AXIS ));

controls.add(buttonstart);
controls.add(buttonstop);
controls.add(buttonpause);
controls.add(buttonresetcanvas);

// Now time increment and current time


JPanel timeindicatorpanel = new JPanel();
timeindicatorpanel.add( labelcurrentdate );
timeindicatorpanel.add( textcurrentdate );

JPanel timeincrementpanel = new JPanel();
timeincrementpanel.add( labeltimebetweenincrements );
timeincrementpanel.add( texttimeincrement );

controls.add( timeindicatorpanel );
controls.add( timeincrementpanel );


content.add( display );
content.add( controls );

setVisible(true);
invalidate();
repaint();

}


This next code draws the JPanel with the indicator arrow buttons:

private void initialisegridbaglayout( Container pane )
{

pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JPanel holdingPanel = new JPanel(new GridBagLayout());

JButton button;


button = new ButtonManipulator("up", this);
button.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1;
c.gridy = 0;
holdingPanel.add(button, c);

button = new ButtonManipulator("left", this);
button.setPreferredSize(new Dimension( 30, 356));
c.gridx = 0;
c.gridy = 1;
holdingPanel.add(button, c);

displayPanel = new DataDisplayPanel( this );

// I've subclassed JPanel here to allow me to draw on it, and
// provide overriden mouse interfaces

displayPanel.setPreferredSize(new Dimension( 420, 356 ));
displayPanel.setBackground( Color.BLACK );

c.gridx = 1;
c.gridy = 1;
holdingPanel.add(displayPanel, c);

button = new ButtonManipulator("right", this);
button.setPreferredSize(new Dimension( 30, 356));
c.gridx = 2;
c.gridy = 1;
holdingPanel.add(button, c);


button = new ButtonManipulator("down", this);
button.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1; //aligned with button 2
c.gridy = 2; //third row
holdingPanel.add(button, c);

pane.add(holdingPanel,new GridBagConstraints());
}


There is nothing, as far as I can see, in anyone of the subclassed components ( ButtonManipulator, DataDisplayPanel, ButtonManipulator) to prevent the components being drawn. But even so, why is just one ButtonManipulator (the "up" button) being drawn at run time, and nothing else apart from the two JTextFields?

Thanks for any help

Paul

dlorde
July 23rd, 2008, 08:52 AM
It's hard to tell from what you've posted - it looks OK. A common mistake that causes odd painting problems is not calling the superclass method when overriding paint methods in a subclassed component, and/or overriding the wrong paint methods.

Debugging is anticipated with distaste, performed with reluctance, and bragged about forever...
Anon.

DrPL
July 23rd, 2008, 09:31 AM
I agree, it is puzzling. Everything looks fine. Here is what I have in my various override swing component paint methods:

For DataDisplayPanel

public void paintComponent( Graphics g )
{
super.paintComponent( g );


// Draw points on map, depending on area, "other info", colour etc.

setBackground( Color.BLACK );

double north = applet.getactualnorthextent();
double south = applet.getactualsouthextent();
double west = applet.getactualwestextent();
double east = applet.getactualeastextent();

Boolean eastwestveto = false;
int counteastwest = 0;

Boolean northsouthveto = false;
int countnorthsouth = 0;

//System.out.println("extent, n, s, e, w = " + north + " " + south + " " + east + " " + west);

if ( west - east > 7 ) eastwestveto = true;
if ( north - south > 7 ) northsouthveto = true;


// Draw lines of longitude first

for (int i = (int) Math.ceil((int) east); i <= (int) Math.floor((int) west); i++)
{
// draw white dot-dash line from top to bottom (x, 0) to (x, getHeight())

//System.out.println("original screen coord = " + i);

if ( eastwestveto && (i % 2 == 0))
{
double [] coords = {i,0};
int [] screencoords = applet.determinescreencoordinates( coords );

//System.out.println("converted screen coords = " + screencoords[0] + " " + screencoords[1]);

g.setColor ( Color.WHITE );

g.drawLine( screencoords[0], 0, screencoords[0], getHeight() );

g.drawString( new String(i + " W"), screencoords[0]+5,15 );
}
counteastwest++;


}


for (int j = (int) Math.ceil((int) south); j <= (int) Math.floor((int) north); j++)
{

//System.out.println("original screen coord = " + i);

if ( northsouthveto && (j % 2 == 0))
{
double [] coords = {0, j};
int [] screencoords = applet.determinescreencoordinates( coords );

//System.out.println("converted screen coords = " + screencoords[0] + " " + screencoords[1]);

g.setColor ( Color.WHITE );

g.drawLine( 0, screencoords[1], getWidth(), screencoords[1] );

g.drawString( new String(j + " N"), 1, screencoords[1]-5 );

}
countnorthsouth++;


}

if ( areadragged )
{

g.setColor ( Color.CYAN);

g.drawRect( screenxinitial, screenyinitial, eastwestextent, northsouthextent );


}

if ( applet.getgraphicsList().getcanread() )
{

// TODO: loop through graphics list and display the items if within drawing area
}


}


I haven't overriden paint() or paintComponent() in the main Applet class.

Button Manipulator.java has this:


public void paintComponent(Graphics g)
{

super.paintComponent(g);

setVisible( true );

if ( direction.equals("up") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 3);
poly.addPoint( (getWidth()/2)+25, 26);
poly.addPoint( (getWidth()/2)-25, 26);
g.fillPolygon(poly);

}
else if ( direction.equals("left") )
{

Polygon poly = new Polygon();
poly.addPoint( 3, getHeight()/2 );
poly.addPoint( 26, (getHeight()/2)+25);
poly.addPoint( 26, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("right") )
{

Polygon poly = new Polygon();
poly.addPoint( 27, getHeight()/2);
poly.addPoint( 3, (getHeight()/2)+25);
poly.addPoint( 3, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("down") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 27);
poly.addPoint( (getWidth()/2)+25, 3);
poly.addPoint( (getWidth()/2)-25, 3);
g.fillPolygon(poly);

}

}

keang
July 23rd, 2008, 10:16 AM
In the init() method you are getting the content pane and setting its layout to FlowLayout. You are then passing a reference to this panel to the initialisegridbaglayout() method where you set it's layout to GridBagLayout. The same panel can't have to two different layouts so the subsequent addition of components in the init() method, without a GridBagConstraints object, maybe causing your problem.

DrPL
July 23rd, 2008, 12:20 PM
I've tried this, but it doesn't work. Can anyone help?

public void init()
{

JPanel screenlayout = new JPanel();
screenlayout.setLayout(new FlowLayout());

JPanel gridbagdisplay = new JPanel();

initialisegridbaglayout( gridbagdisplay );

// etc. etc. initialise other JPanel for controls

screenlayout.add( gridbagdisplay );
screenlayout.add( controls );

}

keang
July 23rd, 2008, 12:25 PM
It what way doesn't it work?

dlorde
July 23rd, 2008, 02:31 PM
... The same panel can't have to two different layouts so the subsequent addition of components in the init() method, without a GridBagConstraints object, maybe causing your problem.It shouldn't be a problem - the new layout just replaces the old one and the panel is invalidated.

However, it's not good practice to set the content pane layout directly, better to set the frame layout and let the frame decide how to do it.

Any programming problem can be solved by adding a level of indirection...
Anon.

dlorde
July 23rd, 2008, 02:58 PM
I patched together the posted code, adding as little as possible to make it run, and when I run it in the applet viewer all the components are displayed.

I haven't tried running it in a browser... are you running it in a browser or the applet viewer?

Bad code isn't bad, its just misunderstood...
Anon.

keang
July 23rd, 2008, 03:09 PM
It shouldn't be a problem - the new layout just replaces the old one and the panel is invalidated.Yes, but the components added in the init method after the panel has been changed to a GridBagLayout aren't added with a constraints object and I don't know how the GridBag layout manager will handle components without a constraints object or if handling will even be consistent.

DrPL
July 23rd, 2008, 05:23 PM
Hi dlorde,
I've tried running it in a browser and appletviewer, and I get the same result on both occasions. I'd like to see your code if you want to email it to me. My email is paul@paullee.com
Hi keang,
I get the same result as in the previous case.

I'm stumped...

Paul

dlorde
July 23rd, 2008, 05:25 PM
Yes, but the components added in the init method after the panel has been changed to a GridBagLayout aren't added with a constraints object and I don't know how the GridBag layout manager will handle components without a constraints object or if handling will even be consistent.I dunno - I'd expect GridBag layout to have sensible defaults. The best way to find out would be to write a dummy applet that does this and see what happens... but I'm strangely disinclined :rolleyes: ;)

By relieving the brain of all unnecessary work, a good notation sets it free to concentrate on more advanced problems, and in effect increases the mental power of the race...
A.N. Whitehead

keang
July 23rd, 2008, 05:40 PM
DrPL can you post/attach a working (or should that be non-working) subset of the code so we can run exactly what you are running.

BTW What version of Java are you using?

DrPL
July 23rd, 2008, 05:54 PM
OK...here goes. A lot of the code is to do with data processing, so I've snipped all that out. By the way, I am running 1.6.0_06. I downloaded it about a fortnight ago, so I think its fairly recent!

By the way, the threading isn't done yet, so if you do get it running, expect lots of exceptions if you press the buttons.


import java.lang.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.math.*;
import java.io.*;
import javax.swing.*;

public class IceDisplayApplet extends JApplet implements Runnable, ActionListener
{

DataDisplayPanel displayPanel;


// NB: ratio of x:y sizes are 4610:6080

JButton buttonresetcanvas = new JButton("reset map"); // Change the screen extent

JLabel labelcurrentdate = new JLabel("Current Date:", Label.LEFT);
JLabel labeltimebetweenincrements = new JLabel("Time Between steps (seconds):", Label.LEFT);

JTextField textcurrentdate = new JTextField("",7);
JTextField texttimeincrement = new JTextField("1",7);

JButton buttonstart = new JButton("start");
JButton buttonpause = new JButton("pause");
JButton buttonstop = new JButton("stop");

ButtonManipulator upbutton;
ButtonManipulator downbutton;
ButtonManipulator leftbutton;
ButtonManipulator rightbutton;


double northextent = 49.00;
double southextent = 40.00;
double westextent = 57.00;
double eastextent = 43.00; // the extent of the data
double actualnorthextent, actualsouthextent, actualwestextent, actualeastextent; // the extent of the map

public double onemilenorth = 6080.0;
public double onemilewest = 4610.0;


public double N(){return 0.0;}
public double NNE(){return 22.5;}
public double NE(){return 45.0;}
public double ENE(){return 67.5;}
public double E(){return 90.0;}
public double ESE(){return 112.5;}
public double SE(){return 135.0;}
public double SSE(){return 157.5;}
public double S(){return 180.0;}
public double SSW(){return 202.5;}
public double SW(){return 225.0;}
public double WSW(){return 247.5;}
public double W (){return 270.0;}
public double WNW(){return 292.5;}
public double NW(){return 315.0;}
public double NNW(){return 337.5;}

public double nauticalmile = 6080.0;

JPanel display, controls, separator;
Container content;

Thread animator;

boolean pauseval;
boolean startval;

public void setscreenextent(int highnorth, int highwest, int height, int width)
{

// actualnorthextent = northextent;
// actualsouthextent = southextent;
// actualwestextent = westextent;
// actualeastextent = eastextent;

double calculatedeastwestextent = (width/displayPanel.getWidth())*(actualwestextent - actualeastextent);
double calculatednorthsouthextent = (height/displayPanel.getHeight())*(actualnorthextent - actualsouthextent);

actualnorthextent = actualnorthextent - (actualnorthextent - actualsouthextent)*highnorth;
actualsouthextent = actualnorthextent - calculatednorthsouthextent;
actualwestextent = actualwestextent - (actualwestextent - actualeastextent)*highwest;
actualeastextent = actualeastextent - calculatedeastwestextent;


}

public double getactualnorthextent()
{
return actualnorthextent;
}

public double getactualsouthextent()
{
return actualsouthextent;
}

public double getactualeastextent()
{
return actualeastextent;
}

public double getactualwestextent()
{
return actualwestextent;
}

public void movemapup()
{
actualnorthextent+=1/6; // this is decimal
actualsouthextent+=1/6;
displayPanel.repaint();
}

public void movemapdown()
{
actualnorthextent-=1/6; // this is decimal!
actualsouthextent-=1/6;
displayPanel.repaint();


}

public void movemapleft()
{
actualwestextent+=1/6;
actualeastextent+=1/6;
displayPanel.repaint();

}

public void movemapright()
{
actualwestextent-=1/6;
actualeastextent-=1/6;
displayPanel.repaint();

}


public void init()
{

resetactuallftorealextent();

pauseval = true;
startval = false;

// draw GUI

content=getContentPane();

content.setLayout(new FlowLayout());

display = new JPanel();

//separator = new JPanel();
//separator.setPreferredSize( new Dimension(100, 50));

controls = new JPanel();

initialisegridbaglayout( content );


//display.add( displayPanel );

buttonstart.addActionListener(this);
buttonstop.addActionListener(this);
buttonpause.addActionListener(this);
buttonresetcanvas.addActionListener(this);

controls.setLayout(new BoxLayout( controls, BoxLayout.Y_AXIS ));

controls.add(buttonstart);
controls.add(buttonstop);
controls.add(buttonpause);
controls.add(buttonresetcanvas);

// Now time increment and current time


JPanel timeindicatorpanel = new JPanel();
timeindicatorpanel.add( labelcurrentdate );
timeindicatorpanel.add( textcurrentdate );

JPanel timeincrementpanel = new JPanel();
timeincrementpanel.add( labeltimebetweenincrements );
timeincrementpanel.add( texttimeincrement );

controls.add( timeindicatorpanel );
controls.add( timeincrementpanel );


content.add( display );
//content.add( separator );
content.add( controls );

setVisible(true);
invalidate();
repaint();

//pack();


}


private void initialisegridbaglayout( Container pane )
{

pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JPanel holdingPanel = new JPanel(new GridBagLayout());


upbutton = new ButtonManipulator("up", this);
upbutton.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1;
c.gridy = 0;
holdingPanel.add(upbutton, c);

leftbutton = new ButtonManipulator("left", this);
leftbutton.setPreferredSize(new Dimension( 30, 356));
c.gridx = 0;
c.gridy = 1;
holdingPanel.add(leftbutton, c);

displayPanel = new DataDisplayPanel( this );
displayPanel.setPreferredSize(new Dimension( 420, 356 ));
displayPanel.setBackground( Color.BLACK );
c.gridx = 1;
c.gridy = 1;
holdingPanel.add(displayPanel, c);

rightbutton = new ButtonManipulator("right", this);
irightbutton.setPreferredSize(new Dimension( 30, 356));
c.gridx = 2;
c.gridy = 1;
holdingPanel.add(rightbutton, c);


downbutton = new ButtonManipulator("down", this);
downbutton.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1; //aligned with button 2
c.gridy = 2; //third row
holdingPanel.add(downbutton, c);

pane.add(holdingPanel,new GridBagConstraints());


}



public void stop()
{
animator = null;
startval = false;
}

public void start()
{

if ( !startval )
{
startval = true;
animator = new Thread(this);
animator.start();
}
}


public void run()
{

while (Thread.currentThread() == animator && !pauseval )
{


}

animator = null;
startval = false;
}

public void actionPerformed(ActionEvent e)
{

if (e.getSource() == buttonstart )
{
pauseval = false;

if ( animator == null )
{
start();
}


}

if (e.getSource() == buttonstop )
{

stop();

}

if (e.getSource() == buttonpause )
{
pauseval = true;


}


if (e.getSource() == buttonresetcanvas )
{

resetactuallftorealextent();
displayPanel.repaint();

}


}



private double convertstringcoordinatetodouble( String coord )
{
// first split up the String
String temp[] = coord.split("\\.");

double first = Double.parseDouble( temp[0] );
double second = Double.parseDouble( temp[1] );

return (first + (second/60.0));

}



public int[] determinescreencoordinates( double coords[] )
{
// where on the screen does this go?

double righthandsidetop = coords[0] - actualeastextent;
double righthandsidebottom = actualwestextent - actualeastextent;

double distancefromrighthandside = righthandsidetop/righthandsidebottom;

double distancefrombottom = (coords[1] - actualsouthextent)/(actualnorthextent - actualsouthextent);

// This gives fractional values from the bottom right hand side
// Shame the origin is the top left hand side

int [] screencoords = new int[2];

screencoords[0] = (int)((1 - distancefromrighthandside)*displayPanel.getWidth());
screencoords[1] = (int)((1 - distancefrombottom)*displayPanel.getHeight());

return screencoords;

}

private void resetactuallftorealextent()
{

actualnorthextent = northextent;
actualsouthextent = southextent;
actualwestextent = westextent;
actualeastextent = eastextent;


}

}




import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class DataDisplayPanel extends JPanel implements MouseListener, MouseMotionListener
{
IceDisplayApplet applet;

// TODO: Tooltips.

int initialx, initialy, finalx, finaly;
Boolean areadragged = false;


int screenxinitial, screenyinitial, eastwestextent, northsouthextent;
int eastwestsize, northsouthsize;


public void mouseClicked( MouseEvent e )
{



}

public void mouseEntered( MouseEvent e )
{

}

public void mouseExited( MouseEvent e )
{

}

public void mousePressed( MouseEvent e )
{

// Initial point for dragged/zoomed area

initialx = e.getX();
initialy = e.getY();
areadragged = true;

}

public void mouseReleased( MouseEvent e )
{
areadragged = false;

// TODO: resize applet area

applet.setscreenextent( screenyinitial, screenxinitial, northsouthextent, eastwestextent );
repaint();
}

public void mouseDragged( MouseEvent e )
{
// Final point for zoomed area

finalx = e.getX();
finaly = e.getY();

eastwestsize = finalx - initialx;

northsouthsize = (int) (eastwestsize/420)*356;


if ( eastwestsize < 0 ) // swipe in this direction <-----
{

if ( finaly > initialy ) // swipe downwards
{
screenxinitial = finalx;
screenyinitial = initialy;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;
}
else // swipe upwards
{
screenxinitial = finalx;
screenyinitial = finaly;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;
}


}
else // swipe in this direction ----->
{
if ( finaly > initialy ) // swipe downwards
{
screenxinitial = initialx;
screenyinitial = initialy;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;

}
else // swipe upwards
{
screenxinitial = initialx;
screenyinitial = finaly;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;

}
}


repaint();


}

public void mouseMoved( MouseEvent e )
{

}


public void paintComponent( Graphics g )
{
super.paintComponent( g );


// Draw points on map, depending on area, "other info", colour etc.

setBackground( Color.BLACK );

double north = applet.getactualnorthextent();
double south = applet.getactualsouthextent();
double west = applet.getactualwestextent();
double east = applet.getactualeastextent();

Boolean eastwestveto = false;
int counteastwest = 0;

Boolean northsouthveto = false;
int countnorthsouth = 0;

if ( west - east > 7 ) eastwestveto = true;
if ( north - south > 7 ) northsouthveto = true;


// Draw lines of longitude first

for (int i = (int) Math.ceil((int) east); i <= (int) Math.floor((int) west); i++)
{

if ( eastwestveto && (i % 2 == 0))
{
double [] coords = {i,0};
int [] screencoords = applet.determinescreencoordinates( coords );


g.setColor ( Color.WHITE );

g.drawLine( screencoords[0], 0, screencoords[0], getHeight() );

g.drawString( new String(i + " W"), screencoords[0]+5,15 );
}
counteastwest++;


}


for (int j = (int) Math.ceil((int) south); j <= (int) Math.floor((int) north); j++)
{


if ( northsouthveto && (j % 2 == 0))
{
double [] coords = {0, j};
int [] screencoords = applet.determinescreencoordinates( coords );

g.setColor ( Color.WHITE );

g.drawLine( 0, screencoords[1], getWidth(), screencoords[1] );

g.drawString( new String(j + " N"), 1, screencoords[1]-5 );

}
countnorthsouth++;


}

if ( areadragged )
{

g.setColor ( Color.CYAN);

g.drawRect( screenxinitial, screenyinitial, eastwestextent, northsouthextent );


}

}


public DataDisplayPanel(IceDisplayApplet applet)
{
this.applet = applet;
}

}



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonManipulator extends JButton
{

String direction;
IceDisplayApplet hostapplet;


public ButtonManipulator( String direction, IceDisplayApplet hostapplet )
{
// Arguments = up, down, left, right

this.direction = direction;

// Arguments = main Applet, so that displaypanel can be changed.

this.hostapplet = hostapplet;

}


public void actionPerformed(ActionEvent e)
{
if ( direction.equals("up") )
{
hostapplet.movemapup();
}
else if ( direction.equals("left") )
{
hostapplet.movemapleft();
}
else if ( direction.equals("right") )
{
hostapplet.movemapright();
}
else if ( direction.equals("down") )
{
hostapplet.movemapdown();
}



}

// Need paint method


public void paintComponent(Graphics g)
{

super.paintComponent(g);

setVisible( true );

if ( direction.equals("up") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 3);
poly.addPoint( (getWidth()/2)+25, 26);
poly.addPoint( (getWidth()/2)-25, 26);
g.fillPolygon(poly);

}
else if ( direction.equals("left") )
{

Polygon poly = new Polygon();
poly.addPoint( 3, getHeight()/2 );
poly.addPoint( 26, (getHeight()/2)+25);
poly.addPoint( 26, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("right") )
{

Polygon poly = new Polygon();
poly.addPoint( 27, getHeight()/2);
poly.addPoint( 3, (getHeight()/2)+25);
poly.addPoint( 3, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("down") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 27);
poly.addPoint( (getWidth()/2)+25, 3);
poly.addPoint( (getWidth()/2)-25, 3);
g.fillPolygon(poly);

}

// add your painting here
}


}


I think thats it. Phew...

dlorde
July 24th, 2008, 05:05 AM
It would help if you used the [CODE]..[/CODE] tags when posting code, so it is readable.

Programs must be written for people to read, and only incidentally for machines to execute...
H. Abelson & G. Sussman

DrPL
July 24th, 2008, 05:32 AM
Sorry. Before this, it has been a long time since I last posted here and I had forgotten about those tags.

keang
July 24th, 2008, 07:07 AM
Your code works on my system in the appletviewer, in IE and in Opera (running on Windows XP Pro).

Personally speaking, I don't think the components are particularly well sized or spaced but they do all display.

DrPL
July 24th, 2008, 07:28 AM
Hi, I had planned to reorganise the controls on the right hand side once I got it all working. The JPanel has to be that size as it displays a lot of data, spread over a wide area. By using the arrow buttons and swiping an area, the user can be more specific about the data that is shown.

...and I still can't get it working. I'm using Vista and Firefox 2.

dlorde
July 24th, 2008, 08:18 AM
Well the initial size is way too small, so it looks a bit weird at first, but when the size is set to something like 800x500, it all looks OK here (in the Applet Viewer).

No comment about the code, though... ;-)

The key to performance is elegance, not batallions of special cases...
J. Bently & D. McIlroy

DrPL
July 24th, 2008, 09:08 AM
Well, as said, the plan was to get it working, then tidy it all up.

Except I can't get it to work :(

keang
July 24th, 2008, 09:54 AM
Well the initial size is way too small, so it looks a bit weird at first, but when the size is set to something like 800x500, it all looks OK here (in the Applet Viewer).You're right it certainly looks a lot better at that size, but as for looking OK I guess that comes down to personal preferences. For instance, if I have a column of buttons I prefer it if they are all the same width and there's a small gap between each button.

Except I can't get it to workI'm grasping at straws here but it might be worth changing the Look and Feel in case the issue is to do with the way Vista is displaying the default L&F. You can do this by adding the following to the beginning of the init() method and uncommenting the L&F you want.
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
// UIManager.setLookAndFeel("javax.swing.plaf.metal.MotifLookAndFeel");
}
catch(Exception e1)
{
e1.printStackTrace();
}

dlorde
July 24th, 2008, 10:58 AM
... as for looking OK I guess that comes down to personal preferences. For instance, if I have a column of buttons I prefer it if they are all the same width and there's a small gap between each button.I agree - by 'OK', I just meant everything seemed to be there. I reserve judgement on the UI design - I guess for a test rig it doesn't really matter much as long as it is functional.

Plan to throw one away; you will anyhow...
F. Brooks

DrPL
July 29th, 2008, 07:39 AM
I've found the section of code that caused the problem. I don't know why though! What I did was strip the applet back to its simplest code, and then gradually add methods until I got to the point where I was before.

The problem is a loop in DataPanelDisplay that calls paintComponent.
The loop accessed an externally stored ArrayList and checks various
parameters (so the correct colour and shape can be chosen for drawing etc.).

My stripped-back applet doesn't have anything in the list, so it should return instantly. I don't know why its preventing the other components from being drawn on the applet though.

dlorde
July 29th, 2008, 11:17 AM
The problem is a loop in DataPanelDisplay that calls paintComponent.Your code should not be calling paintComponent(..), and certainly not in a loop...

paintComponent(..) is a delegate method of JComponent .paint(..), which is called by Swing to paint the UI. You can override the delegate methods of paint(..), but you should always let Swing call them.

If you need to change what gets painted in paintComponent(..), override it and access class member variables that hold the details for your painting.

You might find a browse through Custom Painting (http://java.sun.com/docs/books/tutorial/uiswing/painting/index.html) and Painting in AWT & Swing (http://java.sun.com/products/jfc/tsc/articles/painting/) useful.

No matter how far down the wrong road you have gone, turn back now...
Turkish proverb.

DrPL
July 29th, 2008, 11:25 AM
Sorry, I didn't make myself clear. paintComponent isn't in a loop. The loop is inside paintComponent. The only time I call the JPanel to repaint is when the contents of the loop gets updated or changed as the thread (which I haven't implemented yet) steps through the timestamped data; then it gets put on screen a.s.a.p.

What paintComponent is doing is:
drawing lines of latitude and longitude;
drawing a coloured rectangle to denote a selected/dragged area
drawing coloured shapes on screen to denote data, by looping through an updating list.

It is this last step that is causing the problem.

dlorde
July 29th, 2008, 04:15 PM
drawing coloured shapes on screen to denote data, by looping through an updating list.

It is this last step that is causing the problem.How long does this loop take to finish (how many times round the loop) ? As you know from the links I posted, the paint methods should be completed as rapidly as possible; any delay will seriously affect the display of the whole UI. Any loop should be written to finish in minimum time with as few iterations as possible.

If that isn't the problem, I guess we'll need to see more code - I'm all guessed out :rolleyes:

The important thing in science is not so much to obtain new facts as to discover new ways of think about them...
W. Bragg

DrPL
July 29th, 2008, 05:01 PM
The paintComponent method would be called about 28 times, with a seconds delay in between each repaint. The loop would draw no more than 12 items on the screen, and each one would be done as fast as possible. I can't give any metrics at the moment, but there is not much computation taking place in each loop, just lots of it statements, so I don't anticipate there being much latency.

At the moment, the code is just this (below). There isn't much there- most of the drawing code is not implemented as I wanted the GUI working first. I can't see how the below code can cause any latency, as I haven't populated the GraphicsDataList yet, so most of the statements below would be skipped.


// g is of Graphics type

GraphicsDataList glist = applet.getgraphicsList();

int listsize = glist.getList().size();

if( listsize != 0 )
{
if( glist.getcanread()) // only read if we have finished writing to the list
{


// TODO: draw data on screen

for( int a=0; a< listsize ; a++ )
{
DataInfo dinfo = (DataInfo) glist.getList().get(a);

String dtype = dinfo.getdatatype();

if ( dtype.equals("FIELD") )
{
g.setColor( Color.RED );
}
else if ( dtype.equals("BERG") )
{
g.setColor( Color.YELLOW );

}
else if ( dtype.equals("FIELDBERG") )
{
g.setColor( Color.ORANGE );

}

String dsubdata = dinfo.getsubdata();

if ( dsubdata.equals("null") )
{
// Draw shape
// unless coords = 4 points, in which case, draw line

String [][] coords = dinfo.getcoords();

if (coords[1][0].equals("") && coords[1][1].equals(""))
{

}
else
{

}


}
else if ( dsubdata.equals("AREA") )
{
// Draw bounding box
}
else
{
// This is of the format N 8 S 67 - drawline
// unless it contains NOLINE

}

}


}
}

dlorde
July 29th, 2008, 07:05 PM
OK, I don't know what the problem is. Given all the code in compilable form one might be able to debug it, but I for one can't read the large chunk of unformatted code you posted (I thought you might go back and format it for us, but you didn't) and other bits of code aren't much help on their own.

Programs must be written for people to read, and only incidentally for machines to execute...
H. Abelson and G. Sussman

DrPL
July 29th, 2008, 07:32 PM
I thought the above section of problem code was formatted? Its in DataDisplayPanel btw.




import java.lang.*;
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.math.*;
import java.io.*;
import javax.swing.*;

public class IceDisplayApplet extends JApplet implements Runnable, ActionListener
{

DataDisplayPanel displayPanel;


// NB: ratio of x:y sizes are 4610:6080

JButton buttonresetcanvas = new JButton("reset map"); // Change the screen extent

JLabel labelcurrentdate = new JLabel("Current Date:", Label.LEFT);
JLabel labeltimebetweenincrements = new JLabel("Time Increment (seconds):", Label.LEFT);

JTextField textcurrentdate = new JTextField("",7);
JTextField texttimeincrement = new JTextField("1",7);

JButton buttonstart = new JButton("start");
JButton buttonpause = new JButton("pause");
JButton buttonstop = new JButton("stop");

ButtonManipulator upbutton;
ButtonManipulator downbutton;
ButtonManipulator leftbutton;
ButtonManipulator rightbutton;


double northextent = 49.00;
double southextent = 40.00;
double westextent = 57.00;
double eastextent = 43.00; // the extent of the data
double actualnorthextent, actualsouthextent, actualwestextent, actualeastextent; // the extent of the map

public double onemilenorth = 6080.0;
public double onemilewest = 4610.0;


public double N(){return 0.0;}
public double NNE(){return 22.5;}
public double NE(){return 45.0;}
public double ENE(){return 67.5;}
public double E(){return 90.0;}
public double ESE(){return 112.5;}
public double SE(){return 135.0;}
public double SSE(){return 157.5;}
public double S(){return 180.0;}
public double SSW(){return 202.5;}
public double SW(){return 225.0;}
public double WSW(){return 247.5;}
public double W (){return 270.0;}
public double WNW(){return 292.5;}
public double NW(){return 315.0;}
public double NNW(){return 337.5;}

public double nauticalmile = 6080.0;

JPanel display, controls;
Container content;

GraphicsDataList graphicsList;

Thread animator;

boolean pauseval;
boolean startval;


public double getactualnorthextent()
{
return actualnorthextent;
}

public double getactualsouthextent()
{
return actualsouthextent;
}

public double getactualeastextent()
{
return actualeastextent;
}

public double getactualwestextent()
{
return actualwestextent;
}

public void movemapup()
{
actualnorthextent+=0.16667; // this is decimal
actualsouthextent+=0.16667;
displayPanel.repaint();
}

public void movemapdown()
{
actualnorthextent-=0.16667; // this is decimal!
actualsouthextent-=0.16667;
displayPanel.repaint();


}

public void movemapleft()
{
actualwestextent+=0.16667;
actualeastextent+=0.16667;
displayPanel.repaint();

}

public void movemapright()
{
actualwestextent-=0.16667;
actualeastextent-=0.16667;
displayPanel.repaint();

}

public GraphicsDataList getgraphicsList()
{
return graphicsList;

}


public void init()
{

resetactuallftorealextent();

GraphicsDataList graphicsList = new GraphicsDataList();



pauseval = true;
startval = false;

// draw GUI

content=getContentPane();

content.setLayout(new FlowLayout());

display = new JPanel();

controls = new JPanel();

initialisegridbaglayout( content );


buttonstart.addActionListener(this);
buttonstop.addActionListener(this);
buttonpause.addActionListener(this);
buttonresetcanvas.addActionListener(this);

upbutton.addActionListener(this);
downbutton.addActionListener(this);
rightbutton.addActionListener(this);
leftbutton.addActionListener(this);

controls.setLayout(new BoxLayout( controls, BoxLayout.Y_AXIS ));

buttonstart.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonstop.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonpause.setAlignmentX(Component.CENTER_ALIGNMENT);
buttonresetcanvas.setAlignmentX(Component.CENTER_ALIGNMENT);


controls.add(buttonstart);
controls.add(Box.createRigidArea(new Dimension(0,5)));


controls.add(buttonstop);
controls.add(Box.createRigidArea(new Dimension(0,5)));


controls.add(buttonpause);
controls.add(Box.createRigidArea(new Dimension(0,5)));


controls.add(buttonresetcanvas);
controls.add(Box.createRigidArea(new Dimension(0,5)));


// Now time increment and current time


JPanel timeindicatorpanel = new JPanel();
timeindicatorpanel.add( labelcurrentdate );
timeindicatorpanel.add( textcurrentdate );

JPanel timeincrementpanel = new JPanel();
timeincrementpanel.add( labeltimebetweenincrements );
timeincrementpanel.add( texttimeincrement );

controls.add( timeindicatorpanel );
controls.add( timeincrementpanel );


content.add( display );
content.add( controls );

setVisible(true);
invalidate();
repaint();

//pack();


}


private void initialisegridbaglayout( Container pane )
{

pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JPanel holdingPanel = new JPanel(new GridBagLayout());


upbutton = new ButtonManipulator("up", this);
upbutton.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1;
c.gridy = 0;
holdingPanel.add(upbutton, c);

leftbutton = new ButtonManipulator("left", this);
leftbutton.setPreferredSize(new Dimension( 30, 356));
c.gridx = 0;
c.gridy = 1;
holdingPanel.add(leftbutton, c);

displayPanel = new DataDisplayPanel( this );
displayPanel.setPreferredSize(new Dimension( 420, 356 ));
displayPanel.setBackground( Color.BLACK );
c.gridx = 1;
c.gridy = 1;
holdingPanel.add(displayPanel, c);

rightbutton = new ButtonManipulator("right", this);
rightbutton.setPreferredSize(new Dimension( 30, 356));
c.gridx = 2;
c.gridy = 1;
holdingPanel.add(rightbutton, c);


downbutton = new ButtonManipulator("down", this);
downbutton.setPreferredSize(new Dimension( 420, 30));
c.gridx = 1; //aligned with button 2
c.gridy = 2; //third row
holdingPanel.add(downbutton, c);

pane.add(holdingPanel,new GridBagConstraints());


}



public void stop()
{
animator = null;
startval = false;
}

public void start()
{

if ( !startval )
{
startval = true;
animator = new Thread(this);
animator.start();
}
}


public void run()
{

while (Thread.currentThread() == animator && !pauseval )
{


}

animator = null;
startval = false;
}

public void actionPerformed(ActionEvent e)
{

if (e.getSource() == buttonstart )
{
pauseval = false;

if ( animator == null )
{
start();
}


}

if (e.getSource() == buttonstop )
{

stop();

}

if (e.getSource() == buttonpause )
{
pauseval = true;


}


if (e.getSource() == buttonresetcanvas )
{

resetactuallftorealextent();
displayPanel.repaint();

}


if (e.getSource() == upbutton)
{
movemapup();
}
else if (e.getSource() == leftbutton)
{
movemapleft();
}
else if (e.getSource() == rightbutton)
{
movemapright();
}
else if (e.getSource() == downbutton)
{
movemapdown();
}



}



public double convertstringcoordinatetodouble( String coord )
{
// first split up the String
String temp[] = coord.split("\\.");

double first = Double.parseDouble( temp[0] );
double second = Double.parseDouble( temp[1] );

return (first + (second/60.0));

}



public int[] determinescreencoordinates( double coords[] )
{
// where on the screen does this go?


double distancefromlefthandside = actualwestextent - coords[0];
double distancefromtop = actualnorthextent - coords[1];


double latextent = actualnorthextent - actualsouthextent;
double longext = actualwestextent - actualeastextent;

int pixelsfromlefthandside = (int) ((distancefromlefthandside*420)/(actualwestextent -

actualeastextent));

int pixelsfromtop = (int) ((distancefromtop*356)/(actualnorthextent - actualsouthextent));


int [] screencoords = new int[2];

screencoords[0] = pixelsfromlefthandside;
screencoords[1] = pixelsfromtop;

return screencoords;

}

private void resetactuallftorealextent()
{

actualnorthextent = northextent;
actualsouthextent = southextent;
actualwestextent = westextent;
actualeastextent = eastextent;


}

public void resetscreencoords( int screenxinitial, int screenyinitial, int eastwestextent, int

northsouthextent)
{



double northsouth = actualnorthextent - actualsouthextent;
double dummy = actualnorthextent;

actualnorthextent = actualnorthextent - (screenyinitial*northsouth)/356;

actualsouthextent = dummy - ((northsouthextent + screenyinitial)*northsouth)/356;

double eastwest = actualwestextent - actualeastextent;

actualwestextent = actualwestextent - (screenxinitial*eastwest)/420;

dummy = actualwestextent;

actualeastextent = dummy - ((eastwestextent + screenxinitial)*eastwest)/420;

}

}







import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class DataDisplayPanel extends JPanel implements MouseListener, MouseMotionListener
{
IceDisplayApplet applet;

// TODO: Tooltips.

int initialx, initialy, finalx, finaly;
Boolean areadragged = false;


int screenxinitial, screenyinitial, eastwestextent, northsouthextent;
int eastwestsize, northsouthsize;


public void mouseClicked( MouseEvent e )
{

}

public void mouseEntered( MouseEvent e )
{
}

public void mouseExited( MouseEvent e )
{
}

public void mousePressed( MouseEvent e )
{

// Initial point for dragged/zoomed area

initialx = e.getX();
initialy = e.getY();
areadragged = true;

}

public void mouseReleased( MouseEvent e )
{

if ( areadragged )
{


areadragged = false;

// TODO: resize applet area

applet.resetscreencoords( screenyinitial, screenxinitial, northsouthextent, eastwestextent );
repaint();
}

}

public void mouseDragged( MouseEvent e )
{
// Final point for zoomed area

finalx = e.getX();
finaly = e.getY();

eastwestsize = finalx - initialx;

northsouthsize = (int) (eastwestsize*356/420);


if ( eastwestsize < 0 ) // swipe in this direction <-----
{


if ( finaly > initialy ) // swipe downwards
{


screenxinitial = finalx;
screenyinitial = initialy;
eastwestextent = Math.abs( eastwestsize );
northsouthextent = Math.abs(northsouthsize);
}
else // swipe upwards
{

screenxinitial = finalx;
screenyinitial = finaly;
eastwestextent = Math.abs(eastwestsize);
northsouthextent = Math.abs(northsouthsize);
}


}
else // swipe in this direction ----->
{

if ( finaly > initialy ) // swipe downwards
{

screenxinitial = initialx;
screenyinitial = initialy;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;

}
else // swipe upwards
{

screenxinitial = initialx;
screenyinitial = finaly;
eastwestextent = eastwestsize;
northsouthextent = northsouthsize;

}
}


repaint();


}

public void mouseMoved( MouseEvent e )
{
}


public void paintComponent( Graphics g )
{
super.paintComponent( g );


// Draw points on map, depending on area, "other info", colour etc.

setBackground( Color.BLACK );

double north = applet.getactualnorthextent();
double south = applet.getactualsouthextent();
double west = applet.getactualwestextent();
double east = applet.getactualeastextent();

Boolean eastwestveto = false;

Boolean northsouthveto = false;

if ( west - east > 7 ) eastwestveto = true;
if ( north - south > 7 ) northsouthveto = true;


// Draw lines of longitude first

for (int i = (int) Math.ceil((int) east); i <= (int) Math.floor((int) west); i++)
{

if ( eastwestveto && (i % 2 == 0))
{
double [] coords = {i,0};
int [] screencoords = applet.determinescreencoordinates( coords );


g.setColor ( Color.WHITE );

g.drawLine( screencoords[0], 0, screencoords[0], getHeight() );

g.drawString( new String(i + " W"), screencoords[0]+5,15 );
}

}


for (int j = (int) Math.ceil((int) south); j <= (int) Math.floor((int) north); j++)
{


if ( northsouthveto && (j % 2 == 0))
{
double [] coords = {0, j};
int [] screencoords = applet.determinescreencoordinates( coords );

g.setColor ( Color.WHITE );

g.drawLine( 0, screencoords[1], getWidth(), screencoords[1] );

g.drawString( new String(j + " N"), 1, screencoords[1]-5 );

}


}

if ( areadragged )
{

g.setColor ( Color.CYAN);

g.drawRect( screenxinitial, screenyinitial, eastwestextent, northsouthextent );


}


GraphicsDataList glist = applet.getgraphicsList();

int listsize = glist.getList().size();

// START OF PROBLEM AREA

if( listsize != 0 )
{
if( glist.getcanread())
{


// TODO: draw ice, fields, lines etc. on the screen.

for( int a=0; a< listsize ; a++ )
{
DataInfo dinfo = (DataInfo) glist.getList().get(a);

String dtype = dinfo.getdatatype();

if ( dtype.equals("FIELD") )
{
g.setColor( Color.RED );
}
else if ( dtype.equals("BERG") )
{
g.setColor( Color.YELLOW );

}
else if ( dtype.equals("FIELDBERG") )
{
g.setColor( Color.ORANGE );

}

String dsubdata = dinfo.getsubdata();

if ( dsubdata.equals("null") )
{
// Draw shape
// unless coords = 4 points, in which case, draw line

String [][] coords = dinfo.getcoords();

if (coords[1][0].equals("") && coords[1][1].equals(""))
{

}
else
{

}


}
else if ( dsubdata.equals("AREA") )
{
// Draw bounding box
}
else
{
// This is of the format N 8 S 67 - drawline
// unless it contains NOLINE

}

}


}
}

// END OF PROBLEM AREA

}


public DataDisplayPanel(IceDisplayApplet applet)
{
this.applet = applet;
addMouseListener( this );
addMouseMotionListener(this);
}


}






import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ButtonManipulator extends JButton
{

String direction;
IceDisplayApplet hostapplet;


public ButtonManipulator( String direction, IceDisplayApplet hostapplet )
{
// Arguments = up, down, left, right

this.direction = direction;

// Arguments = main Applet, so that displaypanel can be changed.

this.hostapplet = hostapplet;

}


public void paintComponent(Graphics g)
{

super.paintComponent(g);

setVisible( true );

if ( direction.equals("up") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 3);
poly.addPoint( (getWidth()/2)+25, 26);
poly.addPoint( (getWidth()/2)-25, 26);
g.fillPolygon(poly);

}
else if ( direction.equals("left") )
{

Polygon poly = new Polygon();
poly.addPoint( 3, getHeight()/2 );
poly.addPoint( 26, (getHeight()/2)+25);
poly.addPoint( 26, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("right") )
{

Polygon poly = new Polygon();
poly.addPoint( 27, getHeight()/2);
poly.addPoint( 3, (getHeight()/2)+25);
poly.addPoint( 3, (getHeight()/2)-25);
g.fillPolygon(poly);

}
else if ( direction.equals("down") )
{

Polygon poly = new Polygon();
poly.addPoint( getWidth()/2, 27);
poly.addPoint( (getWidth()/2)+25, 3);
poly.addPoint( (getWidth()/2)-25, 3);
g.fillPolygon(poly);

}

}


}





import java.util.*;

public class GraphicsDataList
{
private ArrayList GraphicsList;
Boolean canread;

public GraphicsDataList()
{

GraphicsList = new ArrayList();
canread = false;
}

public ArrayList getList()
{
return GraphicsList;
}

public void setcanread( Boolean value )
{
canread = value;
}

public Boolean getcanread()
{
return canread;
}

}





public class DataInfo
{
String date;
String shipname;
String coords[][];
String subdata;
String datatype;
String info;

DataInfo( String datevals, String shipnameval, String coordvals, String subdatavals, String datatypevals, String infovals )
{

coords = new String[2][2];

coords[1][0]="";
coords[1][1]="";


String temp[] = coordvals.split(" ");

coords[0][0] = temp[0];
coords[0][1] = temp[2];

if (temp.length == 8)
{

coords[1][0] = temp[4];
coords[1][1] = temp[6];

}

date = datevals;
subdata = subdatavals;
shipname = shipnameval;
datatype = datatypevals;
info = infovals;

}

public String getdate()
{
return date;
}

public String getshipname()
{
return shipname;
}

public String[][] getcoords()
{
return coords;
}

public String getsubdata()
{
return subdata;
}

public String getdatatype()
{
return datatype;
}

public String getinfo()
{
return info;
}

}

//JP added flex table