Hey,

I made a small program for the k-clusters algorithm. In the current state though, I'm unable to erase the position of the centers from the previous itterations. If I use paintComponent(g) my jPanel will move down to the right and I have no idea why. (as shown here: http://tinypic.com/r/2eba0j8/6 ).

I'm using NetBeans with the built-in GUI designer tool, and didn't overide any methods.

Recommended Answers

All 9 Replies

Do you have super.paintComponent(g) as the first line in your override? Or have you tried repaint() method of the container?

I didn't override any methods. I'm using jPanel as it is and have a function drawPoints() that uses

Graphics g = jPanel.getGraphics();
g.draw....
g.draw....

Java Swing painting doesn't work like that, no matter how reasonable that looks. Swing is in charge of app drawing, and has all kinds of hidden double-buffering etc behind the scenes. If you simply update that Graphics "behind Swing's back" there's no guarantee about when or even whether that will find its way onto the screen.
This tutorial explains the right way to do it - by overriding paintComponent as Taywin said.

This isn't clear to me, because I'm already using a the default jPanel (provided by the netBeans GUI designer). so even if I have this:

public class MyPanel extends javax.swing.JPanel {
    @Override public void paintComponent(Graphics g) {
        super.paintComponents(g);
        g.draw....

I don't know how to put an instance of MyPanel on the JFrame instead of a JPanel.
Should I change it here:

// <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jTextField2 = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        **jPanel1 = new MyPanel();**

Yes, that's it. You define the subclass, create an instance of it, and use that instance just like any other JPanel, so yes, all the code is OK, including line 12.

Heh, OK, I almost got it to work.

@Override public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.draw...
        .....
        }

I call it from my drawPoints() function by using jPanel1.repaint(). The thing is I'm getting weird artifacts: nothing appears at first unless I mouse-over it. Otherwise it works like I wanted.

EDIT: I think I know why I'm getting it: I'm using arrays to paint (more precisely arrays containing point coords). The thing is I initialize them after I click on a button but paintComponent() is called before that. It then tries to paint by getting data from things that don't exist, hence the error. Any ideas how to fix this behaviour?

EDIT2: A somewhat messy way is to check if the textFields contain something. Since they start out empty this will prevent the painting from occuring at launch (before the array initialisation). Once values are entered we can paint without a problem. But I would still like to avoid calling paintComponent() before I press a button if that's possible at all.

No, you can't stop it! Swing will call that whenever it thinks the panel needs painting, including the very first time it's made visible. You can either test some boolean flag you set to see if you want to paint, or you can keep the panel invisible until you are ready.

Well, I don't want to paint when I launch my program, but apparently the painting method gets called automatically. I can however decide if I want to actually want to paint something, which I'm currently doing by checking if the text input fields contain any values.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.