作为一项任务,我使用HTML表单,servlet,applet和带有两个表的简单数据库编写了一个程序。该程序背后的想法是在html文件的文本框中输入名称,在servlet中获取名称,在数据库中搜索名称并通知用户该名称是否在数据库中。
数据库是MySQL,由两个表组成; tableA在创建表时通过insert输入了三个名字,John Doe,Jane Doe和David Paterson。 TableB用于搜索的名称(无论在HTML的文本字段中输入什么)。如果找到名称,则插入问号,后跟名称。如果没有找到感叹号后跟名称。例如,名称:David Doe不在表A中!David Doe插入表B中。但对于John Doe?John Doe被插入表B中。然后,applet使用tableB显示一条消息,告知tableA中的名称是否(或不是)。
这是相当复杂的。在HTML文本字段中输入名称,然后单击“提交”;它将您带到显示消息/链接的servlet“单击此处查看小程序”。当您单击该链接时,它会显示另一个页面,例如“John Doe在表中”。
我认为一切正常。现在,我似乎无法开始工作的最后一步是让这个小程序消息“John Doe在桌子中”显示为带有白色文本的绿色椭圆形,或者如果名称不是这三个名称中的一个tableA消息应显示为带有黑色文本的红色椭圆形。它只是继续在纯白色背景上显示为常规文本。
我只包含applet代码,有没有人看到我做错了什么?我编写了与独立applet相同的代码,只是为了看看我是否可以在带有白色文本的绿色椭圆中显示消息并且工作正常,所以我不确定它是否是我放置代码的地方。顺便说一下,这位教授没有帮助我向他征求意见,但作为一名在线学生,很难把他压低,而且我对Java很陌生。
Applet代码:
import java.applet.*;
import java.awt.Color;
import java.awt.Graphics;
import java.sql.*;
public class MyApplet extends Applet {
public void paint(Graphics page){
String name = null, message = null;
//page.drawString("XXXXXXXXXXXXXXX", 20, 20);
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/databasea?user=root&password=root");
Statement stmt = con.createStatement();
stmt.executeQuery("use databaseA");
ResultSet rs = stmt.executeQuery("Select * from tableB");
while ( rs.next())
name = rs.getString(1);
if(name.charAt(0) == '?') {
page.setColor(Color.GREEN);
page.fillOval(10, 10, 180, 50);
page.setColor(Color.WHITE);
page.drawString(message, 30, 40);
message = name.substring(1) + " is in the table";
} else {
page.setColor(Color.RED);
page.fillOval(10, 10, 180, 50);
page.setColor(Color.BLACK);
page.drawString(message, 30, 40);
message = name.substring(1) + " is not in the table";
}
String s = "delete from tableB where name = \'" + name + "\'";
stmt.executeUpdate(s);
rs.close();
stmt.close();
con.close();
} catch (Exception e) {
System.out.println("Message: " + e);
//System.exit(0);
}
}
}
答案 0 :(得分:0)
绘制方法用于绘制,你永远不应该在其中执行任何其他操作,尤其是任何耗时的操作,绘制方法可以随时调用,原因很多,其中大多数是你无法控制的。
您需要将加载信息的逻辑与加载信息的逻辑分开,同样,根据其性质,您的结果可能会返回多个结果,您还需要考虑这些结果......
“不幸的是,这是一个课程,我必须使用小程序”是无关紧要的。您应该避免覆盖paint
顶级容器(如JApplet
),因为它们往往包含构成基本显示的其他组件,它们也不是双缓冲的。
您需要将视觉元素分成单独的组件,因此当您进行一些绘画时,它们不会在屏幕上绘制其他组件的过度/不足
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();
}
}
}
}
现在,说了这么多。使用JList
并简单地将新名称添加到ListModel
并依靠ListCellRenderer
来呈现结果实际上会更容易和更合理。然后可以将JList
添加到JScrollPane
,因此,如果显示的信息量,它将自动变为可滚动...
请查看How to use JLists了解详情