fivesigmaevent
asked on
objects or other experts, extending JSlider component that overlaps another component?
Hi,
Some background. I'm learning Java and have been practicing writing apps for about a month now. Wrote GUI connect 4 and some client server stuff and feel that I am close to intermediate stage. Love the language. Now I'm trying to learn some of the more complicated stuff.
I just started reading about swing last night. Looks like the JSlider might be useful for what I'm trying to achieve. So, I'm trying to figure out how to extend a slider to have a vertical line attached to it so it slides left and right along with the slider. The slider's line would be overlapping a northeast quadrant of a cartesian plane. Yesterday I wrote the code below (will change it to swing later to be consistent) which can illustrate it. The red line would be attached to or somehow associated to a JSlider at the bottom of it.
Any suggestions on how to do this? Is this possible with JSlider, or is there a better approach? Can a component overlap another, ie, the line from the slider would be in the foreground and the northeast quadrant in the background? If the slider line sweeps across the quadrant's canvas, does the canvas require repainting?
Any pointers on how to accomplish this are very much appreciated.
// begin file
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener
{
Plane _p;
private final int _WIDTH = 500;
private final int _HEIGHT = 520;
Dimension _plane_size; // size of axis
Point _offset; // axis' offset from Canvas edges
LineComponent _line; // component that shifts left or right, like a slidebar
App()
{
super( "WHATEVER DUDE" );
// call so that createImage() and setExtendedState() will work
// addNotify();
// maximize frame
// setExtendedState( Frame.MAXIMIZED_BOTH );
setSize( _WIDTH, _HEIGHT );
// make a plane and add it to Frame
_plane_size = new Dimension( 200, 200 );
_offset = new Point( 30, 30 );
_line = new LineComponent( new Point( 100, 30 ), new Point( 100, 250));
_p = new Plane( _plane_size, _offset, _line );
add( _p );
// listen to window events
addWindowListener( this );
// show the window
show();
}
void start()
{
_p.drawLineComponent();
repaint();
}
public void windowClosing(WindowEvent e)
{
hide();
dispose();
}
public void windowClosed(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowIconified(WindowEven t e){}
public void windowDeiconified(WindowEv ent e){}
public void windowActivated(WindowEven t e){}
public void windowDeactivated(WindowEv ent e){}
public static void main(String args[])
{
// instantiate the app
App app;
app = new App();
app.start();
}
}
class Plane extends Canvas
{
private Dimension _dimension; // dimensions of plane
private LineComponent _line; // component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Point [] _x_axis; // points for X axes; element 0 is left Point, elem 1 is right Point of axis
private Point [] _y_axis; // points for Y axes; element 0 is top Point, elem 1 is bottom Point of axis
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private boolean _first_time; // first time painting
private final int TOP = 0;
private final int LEFT = 0;
private final int RIGHT = 1;
private final int BOTTOM = 1;
Plane( Dimension d, Point offset, LineComponent line )
{
// save width, height and offset
_dimension = d;
_offset = offset;
_line = line;
_first_time = true;
// setBackground( Color.GRAY );
setSize( d.width + 60, d.height + 80 );
// called so that createImage() will work
// addNotify();
// allocate space for references
_y_axis = new Point[2];
_x_axis = new Point[2];
// save Points to X and Y axes
// Y axis points
_y_axis[0] = new Point( _offset.getX(), _offset.getY() );
_y_axis[1] = new Point( _offset.getX(), _offset.getY() + _dimension.height );
// X axis points
_x_axis[0] = new Point( _offset.getX(), _offset.getY() + _dimension.height );
_x_axis[1] = new Point( _offset.getX() + _dimension.width, _offset.getY() + _dimension.height );
}
public void paint( Graphics g )
{ // use double buffering to draw
if( _first_time )
{ // first time painting, so create an image to draw to
// tried to call addNotify() so I could create an Image and Graphics context
// prior to this, but to no avail
// double buffer to avoid repetitive drawing
_img = createImage( 350, 350 );
_gc = _img.getGraphics();
_first_time = false;
// draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
}
// _img is the in-mem buffer
g.drawImage( _img, 0, 0, this );
}
// draws an X Y axis
public void drawAxes()
{
int [] arrow_x;
int [] arrow_y;
// space for polygon
arrow_x = new int [3];
arrow_y = new int [3];
// draw Y axis with arrow on top
_gc.drawLine( _y_axis[0].getX(), _y_axis[0].getY(), _y_axis[1].getX(), _y_axis[1].getY() );
arrow_x[0] = _y_axis[TOP].getX() - 3;
arrow_x[1] = _y_axis[TOP].getX();
arrow_x[2] = _y_axis[TOP].getX() + 3;
arrow_y[0] = _y_axis[TOP].getY() + 5;
arrow_y[1] = _y_axis[TOP].getY();
arrow_y[2] = _y_axis[TOP].getY() + 5;
_gc.drawPolygon( arrow_x, arrow_y, 3 );
// draw X axis with arrow on right
_gc.drawLine( _x_axis[0].getX(), _x_axis[0].getY(), _x_axis[1].getX(), _x_axis[1].getY() );
arrow_x[0] = _x_axis[RIGHT].getX() - 5;
arrow_x[1] = _x_axis[RIGHT].getX();
arrow_x[2] = _x_axis[RIGHT].getX() - 5;
arrow_y[0] = _x_axis[RIGHT].getY() + 3;
arrow_y[1] = _x_axis[RIGHT].getY();
arrow_y[2] = _x_axis[RIGHT].getY() - 3;
_gc.drawPolygon( arrow_x, arrow_y, 3 );
System.out.println( "drawing y and x axes" );
}
// draws a Line Component
public void drawLineComponent()
{
Color old_color;
old_color = _gc.getColor();
_gc.setColor( Color.RED );
_gc.drawLine( _line.getTop().getX(), _line.getTop().getY(), _line.getBottom().getX(), _line.getBottom().getY() );
_gc.setColor( old_color );
}
}
class LineComponent
{
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent()
{
_top = new Point( 0, 0 );
_bottom = new Point( 0, 0 );
}
LineComponent( Point t, Point b )
{
_top = t;
_bottom = b;
}
void setTop( Point top )
{
_top = top;
}
void setBottom( Point bottom )
{
_bottom = bottom;
}
Point getTop()
{
return _top;
}
Point getBottom()
{
return _bottom;
}
}
// end file
Some background. I'm learning Java and have been practicing writing apps for about a month now. Wrote GUI connect 4 and some client server stuff and feel that I am close to intermediate stage. Love the language. Now I'm trying to learn some of the more complicated stuff.
I just started reading about swing last night. Looks like the JSlider might be useful for what I'm trying to achieve. So, I'm trying to figure out how to extend a slider to have a vertical line attached to it so it slides left and right along with the slider. The slider's line would be overlapping a northeast quadrant of a cartesian plane. Yesterday I wrote the code below (will change it to swing later to be consistent) which can illustrate it. The red line would be attached to or somehow associated to a JSlider at the bottom of it.
Any suggestions on how to do this? Is this possible with JSlider, or is there a better approach? Can a component overlap another, ie, the line from the slider would be in the foreground and the northeast quadrant in the background? If the slider line sweeps across the quadrant's canvas, does the canvas require repainting?
Any pointers on how to accomplish this are very much appreciated.
// begin file
import java.awt.*;
import java.awt.event.*;
public class App extends Frame implements WindowListener
{
Plane _p;
private final int _WIDTH = 500;
private final int _HEIGHT = 520;
Dimension _plane_size; // size of axis
Point _offset; // axis' offset from Canvas edges
LineComponent _line; // component that shifts left or right, like a slidebar
App()
{
super( "WHATEVER DUDE" );
// call so that createImage() and setExtendedState() will work
// addNotify();
// maximize frame
// setExtendedState( Frame.MAXIMIZED_BOTH );
setSize( _WIDTH, _HEIGHT );
// make a plane and add it to Frame
_plane_size = new Dimension( 200, 200 );
_offset = new Point( 30, 30 );
_line = new LineComponent( new Point( 100, 30 ), new Point( 100, 250));
_p = new Plane( _plane_size, _offset, _line );
add( _p );
// listen to window events
addWindowListener( this );
// show the window
show();
}
void start()
{
_p.drawLineComponent();
repaint();
}
public void windowClosing(WindowEvent e)
{
hide();
dispose();
}
public void windowClosed(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowIconified(WindowEven
public void windowDeiconified(WindowEv
public void windowActivated(WindowEven
public void windowDeactivated(WindowEv
public static void main(String args[])
{
// instantiate the app
App app;
app = new App();
app.start();
}
}
class Plane extends Canvas
{
private Dimension _dimension; // dimensions of plane
private LineComponent _line; // component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Point [] _x_axis; // points for X axes; element 0 is left Point, elem 1 is right Point of axis
private Point [] _y_axis; // points for Y axes; element 0 is top Point, elem 1 is bottom Point of axis
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private boolean _first_time; // first time painting
private final int TOP = 0;
private final int LEFT = 0;
private final int RIGHT = 1;
private final int BOTTOM = 1;
Plane( Dimension d, Point offset, LineComponent line )
{
// save width, height and offset
_dimension = d;
_offset = offset;
_line = line;
_first_time = true;
// setBackground( Color.GRAY );
setSize( d.width + 60, d.height + 80 );
// called so that createImage() will work
// addNotify();
// allocate space for references
_y_axis = new Point[2];
_x_axis = new Point[2];
// save Points to X and Y axes
// Y axis points
_y_axis[0] = new Point( _offset.getX(), _offset.getY() );
_y_axis[1] = new Point( _offset.getX(), _offset.getY() + _dimension.height );
// X axis points
_x_axis[0] = new Point( _offset.getX(), _offset.getY() + _dimension.height );
_x_axis[1] = new Point( _offset.getX() + _dimension.width, _offset.getY() + _dimension.height );
}
public void paint( Graphics g )
{ // use double buffering to draw
if( _first_time )
{ // first time painting, so create an image to draw to
// tried to call addNotify() so I could create an Image and Graphics context
// prior to this, but to no avail
// double buffer to avoid repetitive drawing
_img = createImage( 350, 350 );
_gc = _img.getGraphics();
_first_time = false;
// draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
}
// _img is the in-mem buffer
g.drawImage( _img, 0, 0, this );
}
// draws an X Y axis
public void drawAxes()
{
int [] arrow_x;
int [] arrow_y;
// space for polygon
arrow_x = new int [3];
arrow_y = new int [3];
// draw Y axis with arrow on top
_gc.drawLine( _y_axis[0].getX(), _y_axis[0].getY(), _y_axis[1].getX(), _y_axis[1].getY() );
arrow_x[0] = _y_axis[TOP].getX() - 3;
arrow_x[1] = _y_axis[TOP].getX();
arrow_x[2] = _y_axis[TOP].getX() + 3;
arrow_y[0] = _y_axis[TOP].getY() + 5;
arrow_y[1] = _y_axis[TOP].getY();
arrow_y[2] = _y_axis[TOP].getY() + 5;
_gc.drawPolygon( arrow_x, arrow_y, 3 );
// draw X axis with arrow on right
_gc.drawLine( _x_axis[0].getX(), _x_axis[0].getY(), _x_axis[1].getX(), _x_axis[1].getY() );
arrow_x[0] = _x_axis[RIGHT].getX() - 5;
arrow_x[1] = _x_axis[RIGHT].getX();
arrow_x[2] = _x_axis[RIGHT].getX() - 5;
arrow_y[0] = _x_axis[RIGHT].getY() + 3;
arrow_y[1] = _x_axis[RIGHT].getY();
arrow_y[2] = _x_axis[RIGHT].getY() - 3;
_gc.drawPolygon( arrow_x, arrow_y, 3 );
System.out.println( "drawing y and x axes" );
}
// draws a Line Component
public void drawLineComponent()
{
Color old_color;
old_color = _gc.getColor();
_gc.setColor( Color.RED );
_gc.drawLine( _line.getTop().getX(), _line.getTop().getY(), _line.getBottom().getX(), _line.getBottom().getY() );
_gc.setColor( old_color );
}
}
class LineComponent
{
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent()
{
_top = new Point( 0, 0 );
_bottom = new Point( 0, 0 );
}
LineComponent( Point t, Point b )
{
_top = t;
_bottom = b;
}
void setTop( Point top )
{
_top = top;
}
void setBottom( Point bottom )
{
_bottom = bottom;
}
Point getTop()
{
return _top;
}
Point getBottom()
{
return _bottom;
}
}
// end file
ASKER
Hi ozymandias,
> The methods of Point, getX() and getY() return double and you are using them as ints. You will have to cast or convert them or the code will not compile
Oops. :-( Yeah, it's been compiling no problem here. But that's because I forgot that I have a Point.class (wrote it only to discover later on there Java provides a Point class). It has int return types for getX() and getY() in my project directory. Good catch.
> Aside from that, you want a JSlider that controls the horizontal position of the intesecting red line on that graph, correct ?
Yes, that is correct. I figure the line would move with the slider if it was extended as a JSlider, but I'm also not clear if that is the best approach? The graph should be the background. As the line moves horizontally with the slider, it should not obstruct anything painted on the X Y graph.
(Just a side note. Ultimately the graph would display a distribution curve. The app would display some information about where the slider line and curve meet. Somewhat useless, but great practice.)
> The methods of Point, getX() and getY() return double and you are using them as ints. You will have to cast or convert them or the code will not compile
Oops. :-( Yeah, it's been compiling no problem here. But that's because I forgot that I have a Point.class (wrote it only to discover later on there Java provides a Point class). It has int return types for getX() and getY() in my project directory. Good catch.
> Aside from that, you want a JSlider that controls the horizontal position of the intesecting red line on that graph, correct ?
Yes, that is correct. I figure the line would move with the slider if it was extended as a JSlider, but I'm also not clear if that is the best approach? The graph should be the background. As the line moves horizontally with the slider, it should not obstruct anything painted on the X Y graph.
(Just a side note. Ultimately the graph would display a distribution curve. The app would display some information about where the slider line and curve meet. Somewhat useless, but great practice.)
I would not extend JSlider.
I would write a component that has your existing Plane class and displays a JSLider along the X axis. The component listens to the JSlider for events and when they occur it updates the co-ordinates use to draw the line class and then repaints the graph.
I would write a component that has your existing Plane class and displays a JSLider along the X axis. The component listens to the JSlider for events and when they occur it updates the co-ordinates use to draw the line class and then repaints the graph.
I have modified your code so that it sort of does what you decribe.
I had to mes about with GridbagLayout to get the slider to match the length of the x-axis and even now, the tracking between the line and the pointer gets a bit out at either end of the scale, so it definitely needs some tweaking.
// begin file
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class App extends JFrame implements WindowListener {
Plane _p;
private final int _WIDTH = 250;
private final int _HEIGHT = 400;
Dimension _plane_size; // size of axis
Point _offset; // axis' offset from Canvas edges
LineComponent _line;
// component that shifts left or right, like a slidebar
JSlider _slider;
App() {
super("WHATEVER DUDE");
// call so that createImage() and setExtendedState() will work
// addNotify();
// maximize frame
// setExtendedState( Frame.MAXIMIZED_BOTH );
setSize(_WIDTH, _HEIGHT);
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(5,5,5,5);
getContentPane().setLayout (gbl);
// make a plane and add it to Frame
_plane_size = new Dimension(200, 200);
_offset = new Point(5, 5);
_line = new LineComponent(new Point(100, 30), new Point(100, 250));
_p = new Plane(_plane_size, _offset, _line);
gbl.setConstraints(_p,gbc) ;
getContentPane().add(_p);
_slider = new JSlider(JSlider.HORIZONTAL ,0,215,100 );
_slider.addChangeListener( new ChangeListener(){
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusti ng()) {
int xpos = (int)source.getValue();
_p.moveLine(xpos);
_p.drawLineComponent();
_p.repaint();
}
}
});
gbc.gridy = 1;
gbc.weightx = 1;
gbc.insets = new Insets(5,5,5,20);
gbc.fill = GridBagConstraints.HORIZON TAL;
gbl.setConstraints(_slider ,gbc);
getContentPane().add(_slid er);
// listen to window events
addWindowListener(this);
// show the window
show();
}
void start() {
_p.drawLineComponent();
repaint();
}
public void windowClosing(WindowEvent e) {
hide();
dispose();
}
public void windowClosed(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowIconified(WindowEven t e) {
}
public void windowDeiconified(WindowEv ent e) {
}
public void windowActivated(WindowEven t e) {
}
public void windowDeactivated(WindowEv ent e) {
}
public static void main(String args[]) {
// instantiate the app
App app;
app = new App();
app.start();
}
}
class Plane extends Canvas {
private Dimension _dimension; // dimensions of plane
private LineComponent _line;
// component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Point[] _x_axis;
// points for X axes; element 0 is left Point, elem 1 is right Point of axis
private Point[] _y_axis;
// points for Y axes; element 0 is top Point, elem 1 is bottom Point of axis
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private boolean _first_time; // first time painting
private final int TOP = 0;
private final int LEFT = 0;
private final int RIGHT = 1;
private final int BOTTOM = 1;
Plane(Dimension d, Point offset, LineComponent line) {
// save width, height and offset
_dimension = d;
_offset = offset;
_line = line;
_first_time = true;
// setBackground( Color.GRAY );
setSize(d.width + 30, d.height + 10);
// called so that createImage() will work
// addNotify();
// allocate space for references
_y_axis = new Point[2];
_x_axis = new Point[2];
// save Points to X and Y axes
// Y axis points
_y_axis[0] = new Point((int)_offset.getX(), (int)_offset.getY());
_y_axis[1] =
new Point(
(int)_offset.getX(),
(int) (_offset.getY() + _dimension.height));
// X axis points
_x_axis[0] =
new Point(
(int)_offset.getX(),
(int) (_offset.getY() + _dimension.height));
_x_axis[1] =
new Point(
(int) (_offset.getX() + _dimension.width),
(int) (_offset.getY() + _dimension.height));
}
public void paint(Graphics g) { // use double buffering to draw
//if (_first_time) { // first time painting, so create an image to draw to
// tried to call addNotify() so I could create an Image and Graphics context
// prior to this, but to no avail
// double buffer to avoid repetitive drawing
_img = createImage(350, 350);
_gc = _img.getGraphics();
_first_time = false;
// draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
//}
// _img is the in-mem buffer
g.drawImage(_img, 0, 0, this);
}
// draws an X Y axis
public void drawAxes() {
int[] arrow_x;
int[] arrow_y;
// space for polygon
arrow_x = new int[3];
arrow_y = new int[3];
// draw Y axis with arrow on top
_gc.drawLine(
(int)_y_axis[0].getX(),
(int)_y_axis[0].getY(),
(int)_y_axis[1].getX(),
(int)_y_axis[1].getY());
arrow_x[0] = (int)_y_axis[TOP].getX() - 3;
arrow_x[1] = (int)_y_axis[TOP].getX();
arrow_x[2] = (int)_y_axis[TOP].getX() + 3;
arrow_y[0] = (int)_y_axis[TOP].getY() + 5;
arrow_y[1] = (int)_y_axis[TOP].getY();
arrow_y[2] = (int)_y_axis[TOP].getY() + 5;
_gc.drawPolygon(arrow_x, arrow_y, 3);
// draw X axis with arrow on right
_gc.drawLine(
(int)_x_axis[0].getX(),
(int)_x_axis[0].getY(),
(int)_x_axis[1].getX(),
(int)_x_axis[1].getY());
arrow_x[0] = (int)_x_axis[RIGHT].getX() - 5;
arrow_x[1] = (int)_x_axis[RIGHT].getX() ;
arrow_x[2] = (int)_x_axis[RIGHT].getX() - 5;
arrow_y[0] = (int)_x_axis[RIGHT].getY() + 3;
arrow_y[1] = (int)_x_axis[RIGHT].getY() ;
arrow_y[2] = (int)_x_axis[RIGHT].getY() - 3;
_gc.drawPolygon(arrow_x, arrow_y, 3);
System.out.println("drawin g y and x axes");
}
// draws a Line Component
public void drawLineComponent() {
Color old_color;
old_color = _gc.getColor();
_gc.setColor(Color.RED);
_gc.drawLine(
(int)_line.getTop().getX() ,
(int)_line.getTop().getY() ,
(int)_line.getBottom().get X(),
(int)_line.getBottom().get Y());
_gc.setColor(old_color);
}
public void moveLine(int x){
_line.setTop(new Point(x,(int)_line.getTop( ).getY())) ;
_line.setBottom(new Point(x,(int)_line.getBott om().getY( )));
}
}
class LineComponent {
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent() {
_top = new Point(0, 0);
_bottom = new Point(0, 0);
}
LineComponent(Point t, Point b) {
_top = t;
_bottom = b;
}
void setTop(Point top) {
_top = top;
}
void setBottom(Point bottom) {
_bottom = bottom;
}
Point getTop() {
return _top;
}
Point getBottom() {
return _bottom;
}
}
// end file
I had to mes about with GridbagLayout to get the slider to match the length of the x-axis and even now, the tracking between the line and the pointer gets a bit out at either end of the scale, so it definitely needs some tweaking.
// begin file
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class App extends JFrame implements WindowListener {
Plane _p;
private final int _WIDTH = 250;
private final int _HEIGHT = 400;
Dimension _plane_size; // size of axis
Point _offset; // axis' offset from Canvas edges
LineComponent _line;
// component that shifts left or right, like a slidebar
JSlider _slider;
App() {
super("WHATEVER DUDE");
// call so that createImage() and setExtendedState() will work
// addNotify();
// maximize frame
// setExtendedState( Frame.MAXIMIZED_BOTH );
setSize(_WIDTH, _HEIGHT);
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(5,5,5,5);
getContentPane().setLayout
// make a plane and add it to Frame
_plane_size = new Dimension(200, 200);
_offset = new Point(5, 5);
_line = new LineComponent(new Point(100, 30), new Point(100, 250));
_p = new Plane(_plane_size, _offset, _line);
gbl.setConstraints(_p,gbc)
getContentPane().add(_p);
_slider = new JSlider(JSlider.HORIZONTAL
_slider.addChangeListener(
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusti
int xpos = (int)source.getValue();
_p.moveLine(xpos);
_p.drawLineComponent();
_p.repaint();
}
}
});
gbc.gridy = 1;
gbc.weightx = 1;
gbc.insets = new Insets(5,5,5,20);
gbc.fill = GridBagConstraints.HORIZON
gbl.setConstraints(_slider
getContentPane().add(_slid
// listen to window events
addWindowListener(this);
// show the window
show();
}
void start() {
_p.drawLineComponent();
repaint();
}
public void windowClosing(WindowEvent e) {
hide();
dispose();
}
public void windowClosed(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowIconified(WindowEven
}
public void windowDeiconified(WindowEv
}
public void windowActivated(WindowEven
}
public void windowDeactivated(WindowEv
}
public static void main(String args[]) {
// instantiate the app
App app;
app = new App();
app.start();
}
}
class Plane extends Canvas {
private Dimension _dimension; // dimensions of plane
private LineComponent _line;
// component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Point[] _x_axis;
// points for X axes; element 0 is left Point, elem 1 is right Point of axis
private Point[] _y_axis;
// points for Y axes; element 0 is top Point, elem 1 is bottom Point of axis
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private boolean _first_time; // first time painting
private final int TOP = 0;
private final int LEFT = 0;
private final int RIGHT = 1;
private final int BOTTOM = 1;
Plane(Dimension d, Point offset, LineComponent line) {
// save width, height and offset
_dimension = d;
_offset = offset;
_line = line;
_first_time = true;
// setBackground( Color.GRAY );
setSize(d.width + 30, d.height + 10);
// called so that createImage() will work
// addNotify();
// allocate space for references
_y_axis = new Point[2];
_x_axis = new Point[2];
// save Points to X and Y axes
// Y axis points
_y_axis[0] = new Point((int)_offset.getX(),
_y_axis[1] =
new Point(
(int)_offset.getX(),
(int) (_offset.getY() + _dimension.height));
// X axis points
_x_axis[0] =
new Point(
(int)_offset.getX(),
(int) (_offset.getY() + _dimension.height));
_x_axis[1] =
new Point(
(int) (_offset.getX() + _dimension.width),
(int) (_offset.getY() + _dimension.height));
}
public void paint(Graphics g) { // use double buffering to draw
//if (_first_time) { // first time painting, so create an image to draw to
// tried to call addNotify() so I could create an Image and Graphics context
// prior to this, but to no avail
// double buffer to avoid repetitive drawing
_img = createImage(350, 350);
_gc = _img.getGraphics();
_first_time = false;
// draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
//}
// _img is the in-mem buffer
g.drawImage(_img, 0, 0, this);
}
// draws an X Y axis
public void drawAxes() {
int[] arrow_x;
int[] arrow_y;
// space for polygon
arrow_x = new int[3];
arrow_y = new int[3];
// draw Y axis with arrow on top
_gc.drawLine(
(int)_y_axis[0].getX(),
(int)_y_axis[0].getY(),
(int)_y_axis[1].getX(),
(int)_y_axis[1].getY());
arrow_x[0] = (int)_y_axis[TOP].getX() - 3;
arrow_x[1] = (int)_y_axis[TOP].getX();
arrow_x[2] = (int)_y_axis[TOP].getX() + 3;
arrow_y[0] = (int)_y_axis[TOP].getY() + 5;
arrow_y[1] = (int)_y_axis[TOP].getY();
arrow_y[2] = (int)_y_axis[TOP].getY() + 5;
_gc.drawPolygon(arrow_x, arrow_y, 3);
// draw X axis with arrow on right
_gc.drawLine(
(int)_x_axis[0].getX(),
(int)_x_axis[0].getY(),
(int)_x_axis[1].getX(),
(int)_x_axis[1].getY());
arrow_x[0] = (int)_x_axis[RIGHT].getX()
arrow_x[1] = (int)_x_axis[RIGHT].getX()
arrow_x[2] = (int)_x_axis[RIGHT].getX()
arrow_y[0] = (int)_x_axis[RIGHT].getY()
arrow_y[1] = (int)_x_axis[RIGHT].getY()
arrow_y[2] = (int)_x_axis[RIGHT].getY()
_gc.drawPolygon(arrow_x, arrow_y, 3);
System.out.println("drawin
}
// draws a Line Component
public void drawLineComponent() {
Color old_color;
old_color = _gc.getColor();
_gc.setColor(Color.RED);
_gc.drawLine(
(int)_line.getTop().getX()
(int)_line.getTop().getY()
(int)_line.getBottom().get
(int)_line.getBottom().get
_gc.setColor(old_color);
}
public void moveLine(int x){
_line.setTop(new Point(x,(int)_line.getTop(
_line.setBottom(new Point(x,(int)_line.getBott
}
}
class LineComponent {
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent() {
_top = new Point(0, 0);
_bottom = new Point(0, 0);
}
LineComponent(Point t, Point b) {
_top = t;
_bottom = b;
}
void setTop(Point top) {
_top = top;
}
void setBottom(Point bottom) {
_bottom = bottom;
}
Point getTop() {
return _top;
}
Point getBottom() {
return _bottom;
}
}
// end file
ASKER
ozymandias, I ran your changes. Very cool. Give me some time to look over the code and I will get back to ya.
ASKER
ozymandias,
First, thanks for your time and patience. Very helpful. If you bear with me for a little longer, I can increase points a little bit more for you since I have some more related questions and Community Service added missing points to my account.
> I have modified your code so that it sort of does what you decribe.
Yes it's very close. However, the line doesn't appear in motion or animated as the slider is dragged and the line itself cannot be dragged with the mouse cursor. Any ideas? Just an abstract explanation of how to would be great.
> I had to mes about with GridbagLayout to get the slider to match the length of the x-axis and even now, the tracking between the line and the pointer gets a bit out at either end of the scale, so it definitely needs some tweaking.
I noticed that too, but no big deal. It is helping me learn at a faster rate.
> I would write a component that has your existing Plane class and displays a JSLider along the X axis. The component listens to the JSlider for events and when they occur it updates the co-ordinates use to draw the line class and then repaints the graph.
OK. I will try that approach, also trying to use some of the ideas you have coded. I take it that a custom component can be composed of multiple components, both pre-existing and custom made, right? Can you recommened some reading, (books and/or websites are fine) that go into depth about creating custom components?
> public void paint( Graphics g ){
// double buffer to avoid repetitive drawing
_img = createImage(350, 350);
_gc = _img.getGraphics();
Hmmm. With the "if" statement gone in paint(), the _img and _gc code need to be pulled out of paint otherwise the in-memory image gets lost with each call to paint(). The "if" statement was there to prevent this. I would rather instantiate _img and _gc in the constructor but would get a null pointer exception when executing. Supposedly addNotify() would cure this by creating the component peer prior to displaying, but did not seem to help.
>> // draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
// _img is the in-mem buffer
g.drawImage(_img, 0, 0, this);
Seems I should switch the order of g.drawImage() and drawLineComponent() to get the image in the background.
Again, thanks for your assistance.
First, thanks for your time and patience. Very helpful. If you bear with me for a little longer, I can increase points a little bit more for you since I have some more related questions and Community Service added missing points to my account.
> I have modified your code so that it sort of does what you decribe.
Yes it's very close. However, the line doesn't appear in motion or animated as the slider is dragged and the line itself cannot be dragged with the mouse cursor. Any ideas? Just an abstract explanation of how to would be great.
> I had to mes about with GridbagLayout to get the slider to match the length of the x-axis and even now, the tracking between the line and the pointer gets a bit out at either end of the scale, so it definitely needs some tweaking.
I noticed that too, but no big deal. It is helping me learn at a faster rate.
> I would write a component that has your existing Plane class and displays a JSLider along the X axis. The component listens to the JSlider for events and when they occur it updates the co-ordinates use to draw the line class and then repaints the graph.
OK. I will try that approach, also trying to use some of the ideas you have coded. I take it that a custom component can be composed of multiple components, both pre-existing and custom made, right? Can you recommened some reading, (books and/or websites are fine) that go into depth about creating custom components?
> public void paint( Graphics g ){
// double buffer to avoid repetitive drawing
_img = createImage(350, 350);
_gc = _img.getGraphics();
Hmmm. With the "if" statement gone in paint(), the _img and _gc code need to be pulled out of paint otherwise the in-memory image gets lost with each call to paint(). The "if" statement was there to prevent this. I would rather instantiate _img and _gc in the constructor but would get a null pointer exception when executing. Supposedly addNotify() would cure this by creating the component peer prior to displaying, but did not seem to help.
>> // draw the axes
drawAxes();
// draws a Line Component
drawLineComponent();
// _img is the in-mem buffer
g.drawImage(_img, 0, 0, this);
Seems I should switch the order of g.drawImage() and drawLineComponent() to get the image in the background.
Again, thanks for your assistance.
ASKER
Ignore my comment about switching the order of g.drawImage() and drawLineComponent(). :-/
I was hoping to store the background image separate from the red line/component so thats why there was a new Image and Graphics context created. The image would be stored such that it would not require redrawing at each paint() invocation. It would then be painted as background and the red line would be layered in the foreground. Holding the actual graph image in memory could avoid potential flicker problems when drawing. I don't know how feasible that is. Thoughts?
I was hoping to store the background image separate from the red line/component so thats why there was a new Image and Graphics context created. The image would be stored such that it would not require redrawing at each paint() invocation. It would then be painted as background and the red line would be layered in the foreground. Holding the actual graph image in memory could avoid potential flicker problems when drawing. I don't know how feasible that is. Thoughts?
Basically, the composite component we are talking about is a "graphical widget". The framework and patterns for creating these was Java Beans.
There are probably lots of books on this.
I will have to think about this a bit more.
There are probably lots of books on this.
I will have to think about this a bit more.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
BTW, if you want to see the lines drag properly, comment out the :
if (!source.getValueIsAdjusti ng())
statement in each of the ChangeListeners.
This means that the lines will redraw while the slider is being dragged rather than at theh end of the drag.
if (!source.getValueIsAdjusti
statement in each of the ChangeListeners.
This means that the lines will redraw while the slider is being dragged rather than at theh end of the drag.
ASKER
Wow very cool! I have looked over the code and it will take me a little time to get a solid understanding of the changes. Thanks for all the guidance.
Looks like swing is the way to go for something like this. Figure JPanel would be ideal for making the custom component and I'll do some paint optimization with the paintComponent() methods. I think eventually I have the graph display something like a curve, function or something else and points where the line component intersect will be displayed to labels.
Looks like swing is the way to go for something like this. Figure JPanel would be ideal for making the custom component and I'll do some paint optimization with the paintComponent() methods. I think eventually I have the graph display something like a curve, function or something else and points where the line component intersect will be displayed to labels.
ASKER
Thanks ozymandias. Appreciate discussing this and getting some ideas and examples from you.
I increased the points to 100 and give you an A.
I increased the points to 100 and give you an A.
Thanks. That was interesting :0)
Just for fun I added a few buttons that let you add and remove plot points to the graph using the sliders and join then up into a line graph.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.util.*;
public class SliderGraph extends JFrame{
Container contentPane;
JSlider xAxis;
JSlider yAxis;
GraphPlane graph;
LineComponent hLine;
LineComponent vLine;
JLabel xyLabel;
JButton mark;
JButton unmark;
JButton clear;
public SliderGraph(String[] args){
super("SliderGraph");
this.setDefaultCloseOperat ion(EXIT_O N_CLOSE);
contentPane = this.getContentPane();
//contentPane.setLayout(ne w BorderLayout());
vLine = new LineComponent(new Point(150, 1), new Point(150, 300));
hLine = new LineComponent(new Point(1, 150), new Point(300, 150));
graph = new GraphPlane(new Dimension(300,300),new Point(0,0),vLine,hLine);
//contentPane.add(graph,Bo rderLayout .CENTER);
contentPane.setLayout(null );
contentPane.add(graph);
xAxis = new JSlider(JSlider.HORIZONTAL ,0,100,50) ;
xAxis.setMajorTickSpacing( 10);
xAxis.setMinorTickSpacing( 5);
xAxis.setPaintTicks(true);
xAxis.setPaintLabels(true) ;
xAxis.setBorder(BorderFact ory.create EmptyBorde r(0,0,0,0) );
//contentPane.add(xAxis,Bo rderLayout .SOUTH);
contentPane.add(xAxis);
ChangeListener cl = new ChangeListener(){
public void stateChanged(ChangeEvent e) {
int ypos = (int)yAxis.getValue();
int xpos = (int)xAxis.getValue();
xyLabel.setText("x, y = " + xpos + " , " + ypos);
if (e.getSource() == xAxis){
graph.moveVLine(xpos);
}else{
graph.moveHLine(ypos);
}
graph.repaint();
}
};
xAxis.addChangeListener(cl );
yAxis = new JSlider(JSlider.VERTICAL,0 ,100,50);
yAxis.setComponentOrientat ion(Compon entOrienta tion.RIGHT _TO_LEFT);
yAxis.setMajorTickSpacing( 10);
yAxis.setMinorTickSpacing( 5);
yAxis.setPaintTicks(true);
yAxis.setPaintLabels(true) ;
yAxis.setBorder(BorderFact ory.create EmptyBorde r(0,0,0,0) );
//contentPane.add(yAxis,Bo rderLayout .WEST);
contentPane.add(yAxis);
yAxis.addChangeListener(cl );
xyLabel = new JLabel("x, y = 50 , 50");
mark = new JButton("add");
unmark = new JButton("remove");
clear = new JButton("clear");
contentPane.add(xyLabel);
contentPane.add(mark);
contentPane.add(unmark);
contentPane.add(clear);
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEven t ae){
if(ae.getSource() == mark){
addPoint();
}else if(ae.getSource() == unmark){
removePoint();
}else if(ae.getSource() == clear){
clearPoints();
}
}
};
mark.addActionListener(al) ;
unmark.addActionListener(a l);
clear.addActionListener(al );
yAxis.setBounds(10,2,50,31 7);
graph.setBounds(63,10,300, 300);
xAxis.setBounds(53,312,320 ,50);
xyLabel.setBounds(55,370,8 5,20);
mark.setBounds(145,370,70, 20);
unmark.setBounds(220,370,8 5,20);
clear.setBounds(310,370,70 ,20);
}
public void addPoint(){
graph.addPoint((int)xAxis. getValue() ,(int)yAxi s.getValue ());
graph.repaint();
}
public void removePoint(){
graph.removePoint((int)xAx is.getValu e(),(int)y Axis.getVa lue());
graph.repaint();
}
public void clearPoints(){
graph.clearPoints();
graph.repaint();
}
public static void main(String[] args){
SliderGraph sg = new SliderGraph(args);
sg.setSize(450,450);
sg.setVisible(true);
}
class GraphPlane extends Canvas {
private Dimension _dimension; // dimensions of plane
private LineComponent _hLine;
private LineComponent _vLine;
// component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private Vector _points;
GraphPlane(Dimension d, Point offset, LineComponent vLine, LineComponent hLine) {
// save width, height and offset
_dimension = d;
_offset = offset;
_hLine = hLine;
_vLine = vLine;
_points = new Vector();
// setBackground( Color.GRAY );
setSize(d.width + 0, d.height + 0);
// called so that createImage() will work
// addNotify();
}
public void addPoint(int x, int y){
int xpos = (int)(3.0*x);
int ypos = (int)(3.0*(100-y));
Point p = new Point(xpos,ypos);
if (_points.indexOf(p) == -1){
_points.add(p);
System.out.println("added point");
}else{
System.out.println("point exists");
}
}
public void removePoint(int x, int y){
int xpos = (int)(3.0*x);
int ypos = (int)(3.0*(100-y));
Point p = new Point(xpos,ypos);
int i;
if ((i = _points.indexOf(p)) == -1){
System.out.println("no point exists");
}else{
_points.removeElementAt(i) ;
System.out.println("remove d point");
}
}
public void clearPoints(){
_points = new Vector();
}
public void paint(Graphics g) { // use double buffering to draw
_img = createImage(300, 300);
_gc = _img.getGraphics();
drawBorder();
plotPoints();
drawLineComponents();
g.drawImage(_img, 0, 0, this);
}
public void plotPoints(){
Point last = new Point();
for (int i = 0; i < _points.size(); i++){
Point p = (Point)_points.elementAt(i );
_gc.drawRect((int)p.getX() -1,(int)p. getY()-1,3 ,3);
if (i > 0){
_gc.drawLine((int)last.get X(),(int)l ast.getY() ,(int)p.ge tX(),(int) p.getY());
}
last = p;
}
}
public void drawBorder(){
_gc.drawLine(0,0,0,299);
_gc.drawLine(0,0,299,0);
_gc.drawLine(299,0,299,299 );
_gc.drawLine(0,299,299,299 );
}
// draws a Line Component
public void drawLineComponents() {
Color old_color;
old_color = _gc.getColor();
_gc.setColor(Color.RED);
_gc.drawLine(
(int)_vLine.getTop().getX( ),
(int)_vLine.getTop().getY( ),
(int)_vLine.getBottom().ge tX(),
(int)_vLine.getBottom().ge tY());
_gc.setColor(Color.GREEN);
_gc.drawLine(
(int)_hLine.getTop().getX( ),
(int)_hLine.getTop().getY( ),
(int)_hLine.getBottom().ge tX(),
(int)_hLine.getBottom().ge tY());
_gc.setColor(old_color);
}
public void moveVLine(int x){
int xpos = (int)(3.0*x);
_vLine.setTop(new Point(xpos,(int)_vLine.get Top().getY ()));
_vLine.setBottom(new Point(xpos,(int)_vLine.get Bottom().g etY()));
}
public void moveHLine(int y){
int ypos = (int)(3.0*(100-y));
_hLine.setTop(new Point((int)_hLine.getTop() .getX(),yp os));
_hLine.setBottom(new Point((int)_hLine.getBotto m().getX() ,ypos));
}
}
class LineComponent {
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent() {
_top = new Point(0, 0);
_bottom = new Point(0, 0);
}
LineComponent(Point t, Point b) {
_top = t;
_bottom = b;
}
void setTop(Point top) {
_top = top;
}
void setBottom(Point bottom) {
_bottom = bottom;
}
Point getTop() {
return _top;
}
Point getBottom() {
return _bottom;
}
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.util.*;
public class SliderGraph extends JFrame{
Container contentPane;
JSlider xAxis;
JSlider yAxis;
GraphPlane graph;
LineComponent hLine;
LineComponent vLine;
JLabel xyLabel;
JButton mark;
JButton unmark;
JButton clear;
public SliderGraph(String[] args){
super("SliderGraph");
this.setDefaultCloseOperat
contentPane = this.getContentPane();
//contentPane.setLayout(ne
vLine = new LineComponent(new Point(150, 1), new Point(150, 300));
hLine = new LineComponent(new Point(1, 150), new Point(300, 150));
graph = new GraphPlane(new Dimension(300,300),new Point(0,0),vLine,hLine);
//contentPane.add(graph,Bo
contentPane.setLayout(null
contentPane.add(graph);
xAxis = new JSlider(JSlider.HORIZONTAL
xAxis.setMajorTickSpacing(
xAxis.setMinorTickSpacing(
xAxis.setPaintTicks(true);
xAxis.setPaintLabels(true)
xAxis.setBorder(BorderFact
//contentPane.add(xAxis,Bo
contentPane.add(xAxis);
ChangeListener cl = new ChangeListener(){
public void stateChanged(ChangeEvent e) {
int ypos = (int)yAxis.getValue();
int xpos = (int)xAxis.getValue();
xyLabel.setText("x, y = " + xpos + " , " + ypos);
if (e.getSource() == xAxis){
graph.moveVLine(xpos);
}else{
graph.moveHLine(ypos);
}
graph.repaint();
}
};
xAxis.addChangeListener(cl
yAxis = new JSlider(JSlider.VERTICAL,0
yAxis.setComponentOrientat
yAxis.setMajorTickSpacing(
yAxis.setMinorTickSpacing(
yAxis.setPaintTicks(true);
yAxis.setPaintLabels(true)
yAxis.setBorder(BorderFact
//contentPane.add(yAxis,Bo
contentPane.add(yAxis);
yAxis.addChangeListener(cl
xyLabel = new JLabel("x, y = 50 , 50");
mark = new JButton("add");
unmark = new JButton("remove");
clear = new JButton("clear");
contentPane.add(xyLabel);
contentPane.add(mark);
contentPane.add(unmark);
contentPane.add(clear);
ActionListener al = new ActionListener(){
public void actionPerformed(ActionEven
if(ae.getSource() == mark){
addPoint();
}else if(ae.getSource() == unmark){
removePoint();
}else if(ae.getSource() == clear){
clearPoints();
}
}
};
mark.addActionListener(al)
unmark.addActionListener(a
clear.addActionListener(al
yAxis.setBounds(10,2,50,31
graph.setBounds(63,10,300,
xAxis.setBounds(53,312,320
xyLabel.setBounds(55,370,8
mark.setBounds(145,370,70,
unmark.setBounds(220,370,8
clear.setBounds(310,370,70
}
public void addPoint(){
graph.addPoint((int)xAxis.
graph.repaint();
}
public void removePoint(){
graph.removePoint((int)xAx
graph.repaint();
}
public void clearPoints(){
graph.clearPoints();
graph.repaint();
}
public static void main(String[] args){
SliderGraph sg = new SliderGraph(args);
sg.setSize(450,450);
sg.setVisible(true);
}
class GraphPlane extends Canvas {
private Dimension _dimension; // dimensions of plane
private LineComponent _hLine;
private LineComponent _vLine;
// component that shifts left or right, like a slidebar
private Point _offset; // offset from edges of border
private Image _img; // in-mem image for double buffering draw technique
private Graphics _gc; // graphics context
private Vector _points;
GraphPlane(Dimension d, Point offset, LineComponent vLine, LineComponent hLine) {
// save width, height and offset
_dimension = d;
_offset = offset;
_hLine = hLine;
_vLine = vLine;
_points = new Vector();
// setBackground( Color.GRAY );
setSize(d.width + 0, d.height + 0);
// called so that createImage() will work
// addNotify();
}
public void addPoint(int x, int y){
int xpos = (int)(3.0*x);
int ypos = (int)(3.0*(100-y));
Point p = new Point(xpos,ypos);
if (_points.indexOf(p) == -1){
_points.add(p);
System.out.println("added point");
}else{
System.out.println("point exists");
}
}
public void removePoint(int x, int y){
int xpos = (int)(3.0*x);
int ypos = (int)(3.0*(100-y));
Point p = new Point(xpos,ypos);
int i;
if ((i = _points.indexOf(p)) == -1){
System.out.println("no point exists");
}else{
_points.removeElementAt(i)
System.out.println("remove
}
}
public void clearPoints(){
_points = new Vector();
}
public void paint(Graphics g) { // use double buffering to draw
_img = createImage(300, 300);
_gc = _img.getGraphics();
drawBorder();
plotPoints();
drawLineComponents();
g.drawImage(_img, 0, 0, this);
}
public void plotPoints(){
Point last = new Point();
for (int i = 0; i < _points.size(); i++){
Point p = (Point)_points.elementAt(i
_gc.drawRect((int)p.getX()
if (i > 0){
_gc.drawLine((int)last.get
}
last = p;
}
}
public void drawBorder(){
_gc.drawLine(0,0,0,299);
_gc.drawLine(0,0,299,0);
_gc.drawLine(299,0,299,299
_gc.drawLine(0,299,299,299
}
// draws a Line Component
public void drawLineComponents() {
Color old_color;
old_color = _gc.getColor();
_gc.setColor(Color.RED);
_gc.drawLine(
(int)_vLine.getTop().getX(
(int)_vLine.getTop().getY(
(int)_vLine.getBottom().ge
(int)_vLine.getBottom().ge
_gc.setColor(Color.GREEN);
_gc.drawLine(
(int)_hLine.getTop().getX(
(int)_hLine.getTop().getY(
(int)_hLine.getBottom().ge
(int)_hLine.getBottom().ge
_gc.setColor(old_color);
}
public void moveVLine(int x){
int xpos = (int)(3.0*x);
_vLine.setTop(new Point(xpos,(int)_vLine.get
_vLine.setBottom(new Point(xpos,(int)_vLine.get
}
public void moveHLine(int y){
int ypos = (int)(3.0*(100-y));
_hLine.setTop(new Point((int)_hLine.getTop()
_hLine.setBottom(new Point((int)_hLine.getBotto
}
}
class LineComponent {
private Point _top; // top point of line component
private Point _bottom; // bottom pt of line component
LineComponent() {
_top = new Point(0, 0);
_bottom = new Point(0, 0);
}
LineComponent(Point t, Point b) {
_top = t;
_bottom = b;
}
void setTop(Point top) {
_top = top;
}
void setBottom(Point bottom) {
_bottom = bottom;
}
Point getTop() {
return _top;
}
Point getBottom() {
return _bottom;
}
}
}
ASKER
hey ozymandias,
Very neat stuff! I will play around with it more tonight. Will try to add some stuff to it.
Off Topic: Do you happen to know how to draw state machine diagrams in Java or know of any libraries that can be used to do that? If you do, I can start another question thread and address it to you.
Very neat stuff! I will play around with it more tonight. Will try to add some stuff to it.
Off Topic: Do you happen to know how to draw state machine diagrams in Java or know of any libraries that can be used to do that? If you do, I can start another question thread and address it to you.
Not sure what a state machine diagram is.
I use visio for my diagrams stuff like state transition, flow control, UML etc.
There probably is a java package for doing it, but I;ve not come across one.
I use visio for my diagrams stuff like state transition, flow control, UML etc.
There probably is a java package for doing it, but I;ve not come across one.
ASKER
ozymandias,
I see what you are talking about with respect to the composite widget. It uses the model/state and delegate design patterns. Hopefully I will be able to develop without too much struggle.
A state machine diagram is very similar to what you would create with Visio, with a start state, directed edges to other states based on input, and final or acceptance states. I will try a web search for a package that does this, as it is a very complicated task to draw nice state machines.
I see what you are talking about with respect to the composite widget. It uses the model/state and delegate design patterns. Hopefully I will be able to develop without too much struggle.
A state machine diagram is very similar to what you would create with Visio, with a start state, directed edges to other states based on input, and final or acceptance states. I will try a web search for a package that does this, as it is a very complicated task to draw nice state machines.
Aside from that, you want a JSlider that controls the horizontal position of the intesecting red line on that graph, correct ?