Paint methods are for painting, you should never perform any other actions in them, especially any time consuming operations, paint methods can be called at anytime, for many reasons, most of which you don't have control over.
You need to separate the logic of loading the information from the logic of loading it, also, by it's nature, it's possible that your result will return multiple results, which you also need to take into consideration...
"Unfortunately this is for a class and I have to use an applet" is irrelevant. You should avoid overriding paint
of top level containers (like JApplet
) as they tend to contain other components which make up the basic display, they are also not double buffered.
You need to separate the visual elements into separate components, so when you do do some painting, they don't over/under paint other components on the screen
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ExampleApplet extends JApplet {
private ExamplePanel examplePane;
@Override
public void init() {
examplePane = new ExamplePanel();
setLayout(new BorderLayout());
add(examplePane);
JButton check = new JButton("Check");
add(check, BorderLayout.SOUTH);
check.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
load();
}
});
}
public void load() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
try (Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/databasea?user=root&password=root")) {
try (PreparedStatement stmt = con.prepareStatement("Select * from tableB")) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
String name = rs.getString(1);
examplePane.addName(name);
try (PreparedStatement delete = con.prepareStatement("delete from tableB where name = ?")) {
delete.setString(1, name);
} catch (SQLException exp) {
exp.printStackTrace();
}
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException exp) {
exp.printStackTrace();
}
}
public class ExamplePanel extends JPanel {
private List<String> names;
public ExamplePanel() {
names = new ArrayList<>(25);
}
public void addName(String name) {
names.add(name);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
FontMetrics fm = g.getFontMetrics();
int x = 0;
int y = 0;
for (String name : names) {
String message = null;
if (name.charAt(0) == '?') {
g.setColor(Color.GREEN);
g.fillOval(x, y, fm.getHeight(), fm.getHeight());
g.setColor(Color.WHITE);
message = name.substring(1) + " is in the table";
} else {
g.setColor(Color.RED);
g.fillOval(x, y, fm.getHeight(), fm.getHeight());
g.setColor(Color.BLACK);
message = name.substring(1) + " is not in the table";
}
g.drawString(message, fm.getHeight(), y);
y += fm.getHeight();
}
}
}
}
Now, having said all that. It would actually be a lot easier and more reasonable to use a JList
and simply add the new names to a ListModel
and rely on the ListCellRenderer
to render the result. The JList
could then be added to a JScrollPane
, so if the amount of information been displayed, it would automatically become scrollable...
Take a look at How to use JLists for more details