0

I am a newb and am trying to get a line to draw with my xslider and yslider so it would create cross hairs on the canvas panel. I cannot figure this out. The idea is that when I push the "Show" button a circle is to appear centered on the crosshairs set by the sliders. I used internalframes to create the button location and canvas for the circle and sliders. I need lines connected to the sliders. I cannot change the coding as to how the sliders work in tandem, part of expectations. Please assist.

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

public class CircleViewer2 extends JPanel
{
//Variables
Ellipse2D.Double circle;
static Color FillColor = Color.blue;
static String ShowHideName = null;
static JSlider xSlider;
static JSlider xSlider2;
static JSlider ySlider;
static JSlider ySlider2;

//Creation of the circle utilizing Ellipse2D
public CircleViewer2(int radius)
{
    circle = new Ellipse2D.Double(0, 0, radius, radius);
    setOpaque(false);
}

//Setting PreferredSize
public Dimension getPreferredSize()
{
    Rectangle bounds = circle.getBounds();
    return new Dimension(bounds.width, bounds.height);
}

//Establishing parameters for Drawing the Circle Via Paint
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(FillColor);
    g2.fill(circle);
}

public static void main(String[] args)
{
    final JPanel center = new JPanel();
    center.setLayout(null);
    center.setPreferredSize(new Dimension(400,400));
    ShowHideName = "Show";    
    final JButton ShowHideButton = new JButton(ShowHideName);
    ShowHideButton.setPreferredSize(new Dimension(75, 25));
    ShowHideButton.addActionListener( new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            if (ShowHideName.equals("Show"))
            {
                int xCoord = xSlider.getValue();
                System.out.println(xCoord);
                int yCoord = ySlider.getValue();
                System.out.println(yCoord);
                CircleViewer2 component = new CircleViewer2(50);
                component.setLocation(xCoord,yCoord);
                component.setSize(component.getPreferredSize());
                center.add(component);
                ShowHideName = "Hide";
                center.repaint();
            } 
            else
            {
                ShowHideName = "Show";
                center.removeAll(); 
                center.updateUI();
            }
            ShowHideButton.setText(ShowHideName);
         }
    });

    final JButton ColorButton = new JButton("Color");
    ColorButton.setPreferredSize(new Dimension(75, 25));
    ColorButton.addActionListener( new ActionListener()
    {
        public void actionPerformed(ActionEvent event)
        {
            FillColor = JColorChooser.showDialog(null,  "Pick a Color", Color.blue);
        }
    });

    JFrame frame = new JFrame();
    JInternalFrame canvas = new JInternalFrame();
    JInternalFrame buttonFrame = new JInternalFrame();
    JPanel buttonPanel = new JPanel();
    buttonPanel.add(ShowHideButton);
    buttonPanel.add(ColorButton);
    javax.swing.plaf.InternalFrameUI ifu= buttonFrame.getUI();
    ((javax.swing.plaf.basic.BasicInternalFrameUI)ifu).setNorthPane(null);
    buttonFrame.setBounds(0, 500, 500, 200);
    buttonFrame.add(buttonPanel, BorderLayout.CENTER);
    buttonFrame.setVisible(true);
    xSlider = new JSlider(SwingConstants.HORIZONTAL,0,380,10);
    BoundedRangeModel xmodel = xSlider.getModel();
    xSlider2 = new JSlider(SwingConstants.HORIZONTAL);
    xSlider2.setModel(xmodel);
    ySlider = new JSlider(SwingConstants.VERTICAL,0,350,10);
    BoundedRangeModel ymodel = ySlider.getModel();
    ySlider.setInverted(true);
    ySlider2 = new JSlider(SwingConstants.VERTICAL);
    ySlider2.setModel(ymodel);
    ySlider2.setInverted(true);
    canvas.add(center, BorderLayout.CENTER);
    canvas.add(xSlider, BorderLayout.SOUTH);
    canvas.add(xSlider2, BorderLayout.NORTH);
    canvas.add(ySlider, BorderLayout.EAST);
    canvas.add(ySlider2, BorderLayout.WEST);
    canvas.setBounds(0, 0, 500, 550);
    canvas.setVisible(true);
    javax.swing.plaf.InternalFrameUI ifu2 = canvas.getUI();
    ((javax.swing.plaf.basic.BasicInternalFrameUI)ifu2).setNorthPane(null);
    frame.add(canvas, BorderLayout.NORTH);
    frame.add(buttonFrame, BorderLayout.SOUTH);
    frame.setBounds(0, 0, 500, 530);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

mKorbel
  • 109,525
  • 20
  • 134
  • 319

2 Answers2

1

Your code looks way more complex than it needs to be, and I would try to simplify it greatly. Some suggestions:

  • Get rid of all the JInternalFrames and use JPanels instead.
  • Create a JPanel, say called drawingPanel, that has its paintComponent(Graphics g) overridden and perhaps its getPreferredSize() overridden, place this JPanel BorderLayout.CENTER in your main GUI.
  • In the paintComponent method, have the logic to draw the circles and the crosshairs based on fields of your class.
  • When a JSlider moves, have its ChangeListener change the state of the corresponding field, and then have it call repaint() on the drawing panel so that it will draw the changes.
  • When the show button is pressed, have it change the state of a boolean variable and then call repaint().
  • Have the drawingPanel use the boolean in its paintComponent method to decide whether or not to draw the filled circle.
  • Have the drawingPanel draw the lines in its paintComponent method based on the value returned by the JSliders. Again you're calling repaint in the JSlider's listeners, so the lines will move.
  • Do not add and remove components on button clicks since this adds unnecessary complexity which makes things much harder to code.
  • Don't move the center component or any component. Just use the fixed drawingPanel JPanel and move the location of the circle and the lines that it draws.

Since this is homework, I'm going to avoid posting code as the coding should be up to you. Much luck!

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

This is not a good implementation of the problem. You can inherit the JFrame and make the code clearer, it's the common method to play with Swing components. Any way, Add a change Listener to your sliders and change the location of the Center Panel according to the Sliders Value. Something like that:

xSlider.addChangeListener( e -> {
    center.setLocation(new Point(xSlider.getValue(), (int) center.getLocation().getY());
});

and so on. This is a good place to start with Java/Swing GUI best practices

Community
  • 1
  • 1
BilalDja
  • 1,072
  • 1
  • 9
  • 17
  • Nah, there's no need to extend JFrame. Better to extend a fixed location JPanel and draw in it rather than to move JPanels around. 1+ though for noting that the original poster was not using ChangeListeners. I assumed that he was. – Hovercraft Full Of Eels Sep 30 '14 at 21:37
  • As he said he is a newB, I give him a working code to play with, and a resource to learn the good habites. – BilalDja Sep 30 '14 at 21:39
  • The JFrame is a minor quibble, but I do think that his code will be much simpler if moves a "logical" circle rather than moves a physical component. – Hovercraft Full Of Eels Sep 30 '14 at 21:46
  • Yes I agree, it will be cleaner if he override the paintComponent methode of the drawing panel – BilalDja Sep 30 '14 at 21:50