2

I have an assignment in which I have to allow a user to plot a graph using a quadratic equation.

I managed to draw the skeleton of the graph, and now I am trying to display the "control panel" for the user to input the values.

I have 4 files:

  • graph.java
  • panel.java
  • panelB.java
  • panelC.java

My problem is when I run the code it is displaying only the panel.java even in the container where it should display the other two panels.

panel.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.JPanel;


public class panel extends JPanel {

    public panel(){
        this.setBackground(Color.yellow);
    }
}

Can anyone please advise what changes I should do to fix this problem?

I have done some changes to the graph.java file:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.*;

public class GraphApplet extends JApplet{


    public GraphApplet(){
    
    raph p = new Graph();//graph
    
    p.setPreferredSize(new Dimension(760,500));
        conn.add(p,BorderLayout.CENTER);
    }

And now all that is being displayed is the graph.

Regarding the other code, I also made some changes to the class names:

gnjk;.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.JPanel;


public class Graph extends JPanel {

public Graph(){
    this.setBackground(Color.yellow);
    }
   
    public void paintComponent(Graphics p) {
    
        super.paintComponent(p);
    
        Graphics2D graph = (Graphics2D)p;
        
        this.setBackground(Color.yellow);//set background color.
        
        int x,y,y1,x1,a,b,p1x,p1y,p2x,p2y;
        
        int xstart = 7;
        int ystart = 1;
        
        int xfinish = 3;

.......

bhfvhn.java

import javax.swing.*;

import java.awt.*;

import javax.swing.JPanel;


public class ControlsA extends JPanel{

public void init (Box g) {
    
    a = Box.createVerticalBox();
    a.add(new JLabel("Please enter the values below:"));
    a.add(new JLabel("h"));
    

}

}

jknmk.java

import javax.swing.*;

import java.awt.Component;
import java.awt.Dimension;

public class ControlsB extends JPanel{

public void init (Box b) {

    b = Box.createHorizontalBox();
    b.add(new JLabel("a"));
    JTextField f1 = new JTextField("0.0");
    f1.setMaximumSize(new Dimension(100,30));
    b.add(f1);


}
}

Here is an updated to my project:

jkl.java

import java.awt.BorderLayout;
import java.awt.Container;

public class GraphApplet extends JApplet{
  public GraphApplet() {
    public void init(){
        SwingUtilities.invokeLater(new Runnable() {
         
         public void run(){
             Container conn = getContentPane();
             conn.setLayout(new BorderLayout());

             Graph z = new Graph();
             conn.add(p,BorderLayout.CENTER);


             fasfae a = new ControlsA(box1);
             conn.add(a,BorderLayout.LINE_START);

            
             adsfawef b = new ControlsB(box2);
             conn.add(b,BorderLayout.PAGE_END);
         }
        });
        }
        }

    
    
    
    /*Container conn = getContentPane();
    conn.setLayout(new BorderLayout());     
    
    Graph p = new Graph();//graph
    
    p.setPreferredSize(new Dimension(460,560));
    conn.add(p,BorderLayout.CENTER);
    
    Box a = new Box(BoxLayout.Y_AXIS);

    a.setPreferredSize(new Dimension(50,50));
    conn.add(a,BorderLayout.EAST);
    
    Box b = new Box(BoxLayout.X_AXIS);
   
    b.setPreferredSize(new Dimension(201,50));
    conn.add(b,BorderLayout.SOUTH);*/
    //this code is commented not to loose it

vtk.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.JPanel;


class Graph extends JPanel {

public Graph(){
    this.setBackground(Color.yellow);
}
@Override
public Dimension getPreferredSize(){return (new Dimension(460,560)); }

public void paint(Graphics z) {
    
        
    
        Graphics graph = (Graphics2D)z;
        
       
        this.setBackground(Color.yellow).
        
        int x,y,y1,x1,a,b,p1x,p1y,p2x,p2y;
        
        //line co-ordinates
        //the numbers represent the number of boxes on the graph
        int xstart = 7;
        int ystart = 1;
        
        int x = 3;
        int y = 9;
        
        //other variables
        int i = 0;
        int i2 = 0;
        int m = 0;
        int n = 0;
        int m2 = 0;
        int n2 = 0;
        int f2 = 0;
        int g2 = 1;
        
        //ranges
        int f = 5;
        int g = -5;
        
        //change -ve num to +ve
        int g3 = Math.abs(g);
        
        int a1 = g3 + f;
        int b1 = a1;
        
        a = (Height);
        f = (Width);

        }
    }
}

// 6 variables the user has to input

}
@Override
public Dimension getPreferredSize() {return (new Dimension(200,100));}
}

nllkl.java

 @Override
 public Dimension getPreferredSize(){return (new Dimension(201,50));}
}

Still no improvement. I cannot understand what is going on.

Community
  • 1
  • 1
MBC870
  • 373
  • 3
  • 8
  • 16
  • 2
    That applet is adding 3 instances of `panel` as opposed to on each of `panel`, `panelB` & `panelC`. – Andrew Thompson Jun 16 '12 at 09:29
  • BTW - *"I have an assignment"* Were you told to make it as an applet? If not, make a `JFrame` instead. If so, ask the tutor 'why an applet?'. They are harder to develop, debug & deploy, and not something that should be attempted by students, or in any situation where you don't want to cram a perfectly good rich client into a web page (which is an odd mixture at the best of times). – Andrew Thompson Jun 16 '12 at 09:59
  • yes it has to be an applet specifically :S – MBC870 Jun 16 '12 at 10:40
  • *"it has to be an applet specifically"* That **deeply** concerns me. Please ask the question from above of whoever decided that, and mention that the [top provider of answers for applets](http://stackoverflow.com/tags/applet/topusers) on SO is asking (this is a subject about which I have a lot of experience). Get back to me with their answer. – Andrew Thompson Jun 16 '12 at 11:54
  • Based on your 'answer' I'll ask, where do you add components to the `Box`? – Andrew Thompson Jun 16 '12 at 12:09
  • Right (nice screen-shot, BTW) those boxes have a preferred size, but nothing in them! They simply form a 'space' down the right and across the bottom of the applet. Put something inside the `Box` instances like was done in the constructor of the component panels. BTW - the second comment `..BoxLayout.X_AXIS);//vertical` should read `//horizontal` - comments are no good, if they are wrong! – Andrew Thompson Jun 16 '12 at 12:25
  • OK - I've only just seen the 'latest' of the edits. It is time to decide whether the `ControlsA` &`ControlsB` classes should exist at all (though the components inside them are necessary). I believe it is bad design - using inheritance where it should be composition. The way to fix the applet, changes based on that decision. Are they part of the spec. of the homework? – Andrew Thompson Jun 16 '12 at 12:32

2 Answers2

3

The main problems in that code are:

  1. The applet is adding 3 instances of panel as opposed to one each of panel, panelB & panelC.
  2. Neither panelB & panelC ever adds the Box to the panel, so it will not appear.
  3. You intimate in the code that panelB should be vertically aligned, which means it would better fit in the LINE_START (WEST) of the BorderLayout, as opposed to the NORTH.
  4. public void paint(Graphics p) {.. is wrong for panel. Since panel is a Swing JPanel it should be public void paintComponent(Graphics p) {..

Once those things are attended to, this is how it might appear.

graph

Other problems.

  • The only code that needs to extend a class is for the applet itself and panel. In fact, even the panel could be changed to show a BufferedImage (the graph) inside a JLabel
  • The panelB and panelC are entirely redundant, just add a Box directly to the layout area of the parent component needed.
  • The nomenclature is wrong.
    1. Java class names should be EachWordUpperCase
    2. Use meaningful class names - the applet might be GraphApplet, the graphing area Graph, ..I am not sure what to call the last 2 panels, since they carry identical components. If there were but one, I might call it Controls as a class (which is overkill for this), or controls if it were an instance of a plain JPanel or Box.
  • None of the calls to set maximum or preferred size are recommended in this situation. The only case that can be made for it is in the preferred size of the graph itself, but since this appears in the CENTER of applet, a size will be suggested by the applet width/height specified in HTML, minus the natural size of the other components (the CENTER component will get 'the rest of the space').

Update

..how am I going to change the code in my applet so that the applet adds one of each panel(?)

Change:

panel a = new panel();//vertical

To:

panelB a = new panelB(new Box(BoxLayout.Y_AXIS));//vertical

Is the simplest way. Note that it changes if you decide to add the Box directly.

Box a = new Box(BoxLayout.Y_AXIS);//vertical
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • thank you very much for your fast reply. I am new to JAVA, I fixed the Class names, however I might be needing some assistance in the coding to change the main problem 1, meaning how am I going to change the code in my applet so that the applet adds one of each panel... – MBC870 Jun 16 '12 at 10:25
  • See the update. Note that since this effectively homework, it makes more sense to guide you to a solution rather than provide the code directly. – Andrew Thompson Jun 16 '12 at 11:20
  • Thanks you very much for giving me the opportunity to learn, I will amend my code right away and come back with an reply :) – MBC870 Jun 16 '12 at 11:49
  • I amended the changes however this is the output I obtained. The applet is only showing me the graph, and where there is supposed to be the other two JPanels it is just blank. it is still an improvement but ;) – MBC870 Jun 16 '12 at 11:54
  • @AndrewThompson : Again one wonderful answer, any PILL to stop you for a day and earn your points :-) – nIcE cOw Jun 16 '12 at 11:57
  • @Matthew I forgot to add that the custom panels that took a `Box` never added it to the panel in question. Components are not seen unless they are added to a container that will itself become visible. – Andrew Thompson Jun 16 '12 at 12:02
  • Further, my last comment to your most recent observation **is mentioned in point 2)** above. If there is anything I write that you do not understand, please ask me about it. – Andrew Thompson Jun 16 '12 at 12:05
  • I deleted it. Didn't know, I am new to these type of "forums". Back to my code, what is to be done so that I add the components to the container? thanks :) – MBC870 Jun 16 '12 at 12:12
  • BTW - Don't worry about making a mistake or two. There is usually someone around who is willing to help correct it. :) – Andrew Thompson Jun 16 '12 at 12:17
  • *"what is to be done so that I add the components to the container?"* Do the same thing you did when adding them to the `Box` in the constructor of the custom classes! Just move that 'constructor' code into the main class.. – Andrew Thompson Jun 16 '12 at 12:19
  • 1
    @Matthew : May you please update your question, with the latest of inputs you had added to your endeavour, and one small image showing exactly where you want your components to lie, will be very helpful :-) – nIcE cOw Jun 16 '12 at 12:20
  • the question is updated. I would like to place 1 panel to the east side of the border which should be: ControlsA and the other one to the south side, which should be ControlsB. The graph stays where it is. – MBC870 Jun 16 '12 at 12:22
  • @nIcEcOw See the cool new edit! As to how to get those points. A body swap? I might be willing if you have a sexy girlfriend. ;) – Andrew Thompson Jun 16 '12 at 12:27
  • further to my last comment above, it seems that the applet is receiving the positions I want the panels to be placed in, however it is not actually displaying them... The question is updated in order to show what changes I have done to all the three codes as suggested by @Andrew Thompson :) – MBC870 Jun 16 '12 at 12:35
  • Guys give me a hand on this one. http://stackoverflow.com/q/11071722/1460412 Thanks :) – MBC870 Jun 17 '12 at 14:33
2

Please try to run this code now, tell me is this closer to what you wanted ? if so do let me know, so that I can delete my answer. Do watch the changes I had done :

  • in your PanelC class, where instead of using init() method, I made the constructor.
  • Inside your Graph class< i had removed all setPreferredSizes(...) calls, and instead I had overridden getPreferredSize() for each Class extending JPanel. For this visit each Class Panel, PanelB and PanelC.
  • Lastly I had changed the Dimension values supplied to the JPanel, which is to go to the LEFT/LINE_START side, to something that can be seen
  • BEST CHANGE is the use of EDT - Event Dispatch Thread, seems like you really not aware of Concurrency in Swing

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

public class Graph extends JApplet{

    public void init(){

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Container conn = getContentPane();
                conn.setLayout(new BorderLayout());

                Panel p = new Panel();//graph
                conn.add(p,BorderLayout.CENTER);

                Box box1 = new Box(BoxLayout.Y_AXIS);
                PanelB a = new PanelB(box1);//vertical
                conn.add(a,BorderLayout.LINE_START);

                Box box2 = new Box(BoxLayout.X_AXIS);
                PanelC b = new PanelC(box2);//horizontal
                conn.add(b,BorderLayout.PAGE_END);
            }
        });
    }
}

class Panel extends JPanel {

    public Panel(){
        this.setBackground(Color.yellow);
    }

    @Override
    public Dimension getPreferredSize()
    {   
        return (new Dimension(460,560));
    }

    public void paintComponent(Graphics p) {

        super.paintComponent(p);

        Graphics2D graph = (Graphics2D)p;

        Dimension appletSize = this.getSize();
        int appletHeight = (int)(appletSize.height);
        int appletWidth = appletSize.width;

        this.setBackground(Color.yellow);//set background color.

        int x,y,y1,x1,a,b,p1x,p1y,p2x,p2y;

        //line co-ordinates
        //the numbers represent the number of boxes on the graph
        int xstart = 7;
        int ystart = 1;

        int xfinish = 3;
        int yfinish = 9;

        //other variables
        int i = 0;
        int i2 = 0;
        int m = 0;
        int n = 0;
        int m2 = 0;
        int n2 = 0;
        int f2 = 0;
        int g2 = 1;

        //ranges
        int f = 5;
        int g = -5;

        //change -ve num to +ve
        int g3 = Math.abs(g);

        int a1 = g3 + f;
        int b1 = a1;

        y1 = (appletHeight);
        x1 = (appletWidth);
        y = (appletHeight / 2);
        x = (appletWidth / 2);
        a = (appletWidth / a1);
        b = (appletHeight / b1);

        int d = (appletWidth / a1);
        int e = (appletHeight / b1);

        /**
         to determine the
         ammount of pixles there
         is in each box of the
         graph, both y-axis and 
         x-axis
         */
        int xbox = x1 / 10;
        int ybox = y1 / 10;

        //line variables
        //the xstart, ystart, etc represent the number of boxes

        //top point of the line on the graph
        p1x = xbox * xstart;//start x
        p1y = ybox * ystart;//start y

        //lowwer point of the line on the graph
        p2x = xbox * xfinish;//finish x
        p2y = ybox * yfinish;//finish y

        //draw y-axis numbers 
        //(+ve)
        while(f != 0){
            String s = String.valueOf(f);
            p.drawString(s,(x + 5),m + 13);
            m = m + b;
            f = f - 1;
        }
        //(-ve)
        m2 = y;
        while(f2 != g-1){
            String u = String.valueOf(f2);
            p.drawString(u,(x + 5),m2 - 3);
            m2 = m2 + b;
            f2 = f2 - 1;
        }
        //draw x-axis numbers.
        //(-ve)
        while(g != 0){
            String t = String.valueOf(g);
            p.drawString(t,n,y - 5);
            n = n + a;
            g = g + 1;
        }
        //(+ve)
        n2 = x + a;
        while(g2 != g3+1){
            String vw = String.valueOf(g2);
            p.drawString(vw,n2 -10,y - 5);
            n2 = n2 + a;
            g2 = g2 + 1;
        }

        BasicStroke aLine2 = new BasicStroke(1.0F,
           BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
        graph.setStroke(aLine2);

        //notch on numbers and grid lines
        //left to right, top to bottom notches
        int v2 = -5;
        int v5 = 0;
        while(i <= a1-1){
            p.setColor(Color.lightGray);//lightgray line
            p.drawLine(a,0,a,y1);//vertical lightgray
            p.drawLine(0,b,x1,b);//horizontal lightgray
            a = a + d;
            b = b + e;
            i = i + 1;
        }
        //notches
        while(i2 <= a1){
            p.setColor(Color.blue);//notch color
            p.drawString("x",v2+2,y+3);//xaxis
            p.drawString("x",x-4,v5+4);//yaxis
            v5 = v5 + e;
            v2 = v2 + d;
            i2 = i2 + 1;
        }

        //draws the border of the graph
        p.setColor(Color.black);
        Rectangle2D.Float rect = new Rectangle2D.Float(0,0,x1,y1);
        BasicStroke aLine = new BasicStroke(2.5F, 
               BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        graph.setStroke(aLine);
        graph.draw(rect);

        //draw cross
        BasicStroke aLine3 = new BasicStroke(2.5F,
                     BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        graph.setStroke(aLine3);
        p.drawLine(x,0,x,y1); //vertical line
        p.drawLine(0,y,x1,y); //horizontal line

        //display the value of graph width and graph height
        String aw = String.valueOf(x1);
        p.drawString("Graph Width = ", 50,90);
        p.drawString(aw,150,90);
        p.drawString("Graph Height = ", 50,110);
        String ah = String.valueOf(y1);
        p.drawString(ah,156,110);

        //draw line on graph

        BasicStroke aLine4 = new BasicStroke(1.5F,
                         BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        graph.setStroke(aLine4);
        p.setColor(Color.red);

        if(p1x <= x1 && p2x <= x1 && p1y <= y1 && p2y <= y1){
            p.drawLine(p1x,p1y,p2x,p2y);
            Color c = new Color(0,0,0);
            p.setColor(c);
            p.drawString("X", p1x-4,p1y+4);
            p.drawString("X", p2x-4,p2y+4);
        }
        else{
            p.setColor(Color.black);
            p.drawRect(48,34,223,35);
            p.setColor(Color.white);
            p.fillRect(49,35,222,34);
            p.setColor(Color.red);
            p.drawString("Wrong co-ordinates!!!", 50,50);
            p.drawString("Values exceede applet dimensions.", 50,65);
        }
    }
}

class PanelB extends JPanel{

    public PanelB (Box a) {

        a = Box.createVerticalBox();
        a.add(new JLabel("Please enter the values below:"));
        a.add(new JLabel("a"));
        JTextField g1 = new JTextField("0.0");
        g1.setMaximumSize(new Dimension(100,30));
        a.add(g1);
        a.add(new JLabel("b"));
        JTextField g2 = new JTextField("0.0");
        g2.setMaximumSize(new Dimension(100,30));
        a.add(g2);
        a.add(new JLabel("c"));
        JTextField g3 = new JTextField("0.0");
        g3.setMaximumSize(new Dimension(100,30));
        a.add(g3);
        a.add(new JLabel("d"));
        JTextField g4 = new JTextField("0.0");
        g4.setMaximumSize(new Dimension(100,30));
        a.add(g4);
        a.add(new JButton("Plot"));
        a.add(new JButton("Refine"));
        add(a);
    }

    @Override
    public Dimension getPreferredSize()
    {   
        return (new Dimension(200,100));
    }
}

class PanelC extends JPanel{

    public PanelC (Box b) {

        b = Box.createHorizontalBox();
        b.add(new JLabel("a"));
        JTextField f1 = new JTextField("0.0");
        f1.setMaximumSize(new Dimension(100,30));
        b.add(f1);
        b.add(new JLabel("b"));
        JTextField f2 = new JTextField("0.0");
        f2.setMaximumSize(new Dimension(100,30));
        b.add(f2);
        b.add(new JLabel("c"));
        JTextField f3 = new JTextField("0.0");
        f3.setMaximumSize(new Dimension(100,30));
        b.add(f3);
        b.add(new JLabel("d"));
        JTextField f4 = new JTextField("0.0");
        f4.setMaximumSize(new Dimension(100,30));
        b.add(f4);
        b.add(new JButton("Plot"));
        b.add(new JButton("Refine"));
        add(b);
    }

    @Override
    public Dimension getPreferredSize()
    {   
        return (new Dimension(201,50));
    }
}

Here is the HTML file I used :

<html>
    <p> This file launches the 'Graph' applet: Graph.class! </p>  
    <applet code= "Graph.class" height = 550 width = 1000>
        No Java?!
    </applet>
 </html>

Here is the output I am getting :

GRAPH

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
  • *"In your `PanelC` class, where instead of using `init()` method.."* Oh yeah, forgot that. It seemed very odd when `PanelB` used a constructor. – Andrew Thompson Jun 16 '12 at 13:31
  • Exactly, though I am really not in favour of using constructors, when extending something, but just to make life easy I did this, rest your answer is always there to do that trick of explaining things in detail :-) And Moreover, in OP's code he/she never even called `init()` method, that's what prompted me to do this change :-) And this time OP failed to call `PanelB and PanelC` anywhere in the code :( – nIcE cOw Jun 16 '12 at 13:33
  • Hello and thanks for your reply, I made the changes in accordance to your answer and I got a similar thing to my last update in the question but the graph moved to the right hand side of the applet. please see my question again in a couple of minutes since I am going to updated it again. – MBC870 Jun 16 '12 at 13:40
  • Now in the latest edit, OP failed to define any `init()` method for the class which extends `JApplet`. I just missed my BEST Change , LOL , the use of EDT, just mentioned it right now, seems like I just realized what I did, ever since I had learned about EDT from stackoverflow, it's like my head rolls towards this thingy without second thought, so thought OP be doing the same thing, but I looked again and it was missing, then I realized it's a change by me :-), in the code, hehe – nIcE cOw Jun 16 '12 at 13:41
  • Yes, their latest attempt seemed to be partially taking my advice to do way with the custom classes. But they had not taken it far enough, and were still mixing aspects of both approaches. I am still waiting on a definitive answer to whether or not to proceed with the `B` & `C` panels. *"but the graph moved to the right hand side of the applet."* And you cannot figure out what caused that, and how to change it?!? Look at the code closely and check the JavaDocs for the methods and attributes used in the layouts. – Andrew Thompson Jun 16 '12 at 13:43
  • @Matthew : had you tried running the exact copy of the code provided by me ? Since if it runs to your expectations, then you probably needs to watch your code again, to see where you doing wrong, Had you checked your `.html` file too regarding the `height and width` supplied by you. – nIcE cOw Jun 16 '12 at 13:44
  • @ Andrew Thompson What answere I am supposed to tell you? I managed to put every think where it belongs, see my question in a min to see what I was looking for. Thanks again guys for your wonderful help, and I hope someday I become as good as you are... :) – MBC870 Jun 16 '12 at 14:09
  • Then simply change this line `conn.add(a,BorderLayout.LINE_START);` to this `conn.add(a,BorderLayout.LINE_END);`, that will do. – nIcE cOw Jun 16 '12 at 14:14
  • @nIcEcOw sorry but I did not understand your last comment :s can you please repeat? – MBC870 Jun 16 '12 at 14:27
  • If you want an output as shown in the image in your question, then simply replace `conn.add(a,BorderLayout.LINE_START);` in my code with this line `conn.add(a,BorderLayout.LINE_END);`, that's it :-) – nIcE cOw Jun 16 '12 at 14:33