Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>The Basic Structure:</h2> <p>The <code>extends</code> keyword means that <code>DrawPanel</code> inherits from <code>JPanel</code>. In other words, <code>DrawPanel</code> "is a" <code>JPanel</code>. As such, it can override its methods (the ones that aren't marked <code>final</code>). You might want to do that for several reasons. For example, you might want to gain access to the panel's <code>Graphics</code> class, which you could use to draw a circle on the panel, or a bar graph, or a string of text. </p> <p>If you don't override any methods, then when you extend <code>JPanel</code> you get something like this:</p> <pre><code>public class DrawPanel extends JPanel { //TODO not much } </code></pre> <p>However, that's not very useful ...unless you just don't like the name <code>JPanel</code> and want to call it <code>AwesomePanel</code> instead (<em>note: don't do that</em>). If that's all you have, you're better off just creating an <strong>instance</strong> of <code>JPanel</code>, like this: <code>JPanel drawPanel = new JPanel();</code></p> <hr> <h2>paintComponent:</h2> <p>The purpose of extending a <code>JPanel</code> is to override the <code>paintComponent</code> method. The <code>JPanel</code> is invisible until you override <code>paintComponent</code> (<em>note: being invisible is what makes it a useful container for buttons and other components</em>). You are right that the <code>paintComponent</code> method is pre-defined (in the <code>JComponent</code> class if you were wondering), but all that method does is make an empty <code>JPanel</code>. If you want to draw something on the panel, then you need to override it, like this:</p> <pre><code>public class DrawPanel extends JPanel { @Override public void paintComponent(Graphics g) { // &lt;-- HERE! //TODO draw stuff } } </code></pre> <p><em>note: the</em> <code>@Override</code> <em>part is not strictly necessary but it's good practice to include it because it reduces the number runtime errors and improves code readability</em></p> <p>You now have access to the <code>Graphics</code> object <code>g</code> for the panel. <code>Graphics</code> is a helper class that allows you to draw things on the panel, like this:</p> <pre><code>public class DrawPanel extends JPanel { @Override public void paintComponent(Graphics g) { g.drawOval(50, 50, 50, 50); // &lt;-- draws an oval on the panel } } </code></pre> <hr> <h2>super.paintComponent:</h2> <p><em>helpful metaphor (that I just made up): The</em> <code>JPanel</code> <em>is the canvas, the</em> <code>Graphics</code> <em>object is your paintbrush, and</em> <code>super.paintComponent(g)</code> <em>is your eraser. (Also,</em> <code>JFrame</code> <em>is your easel.)</em> </p> <p>So <code>super.paintComponent(g)</code> invokes the <code>paintComponent</code> method from the superclass of <code>JPanel</code> (the <code>JComponent</code> class) to erase whatever is currently drawn on the panel. <strong>This is useful for animation.</strong> </p> <p>For example, consider drawing an analog clock on the panel. You need to refresh it every second, so each second you have to erase the previous clock and redraw the clock, adjusting the second hand. If you don't invoke <code>super.paintComponent(g)</code> before redrawing the clock, it will just keep drawing new clocks on top of the old clocks and in 60 seconds what you'll have is just a filled in circle, more or less. </p> <p>Only one more thing to remember: always call <code>super.paintComponent(g)</code> first in the <code>paintComponent</code> method, like this:</p> <pre><code>public class DrawPanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); // &lt;-- HERE! g.drawOval(50, 50, 50, 50); } } </code></pre> <p>That's it. Feel free to contact me.</p> <hr> <h2>Example:</h2> <p>I created a simple example that uses these concepts to display a string of text on a panel (which is placed inside a frame). Save in your IDE as <strong>TestPanel.java</strong>.</p> <pre><code>import java.awt.*; import java.util.*; import javax.swing.*; /** * A frame containing a panel that is sometimes red and sometimes * blue. Also, it displays the word to go with it. * * Inspired by www.sometimesredsometimesblue.com. * */ public class TestPanel extends JPanel { private Random random = new Random(); private boolean isRed; private String s = ""; public TestPanel() { //randomly determine whether the background should be red isRed = random.nextBoolean(); //set the background to blue setBackground(Color.BLUE); s = "BLUE"; //if 'isRed' is true, set the background to red if (isRed) { setBackground(Color.RED); s = "RED"; } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); //write either "RED" or "BLUE" using graphics g.setColor(Color.WHITE); g.setFont(new Font("serif", Font.BOLD, 60)); g.drawString(s, getWidth() / 2 - g.getFontMetrics().stringWidth(s) / 2, getHeight() / 2 + g.getFontMetrics().getHeight() / 2); } //main method: create an instance of TestPanel and output it on a JFrame public static void main(String[] args) { JFrame f = new JFrame(); f.setSize(500, 500); f.setTitle("Sometimes Red, Sometimes Blue"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setContentPane(new TestPanel()); f.setVisible(true); } }</code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload