As an assignment I have written a program using an HTML form, a servlet, an applet and a simple database with two tables. The idea behind this program is to enter a name in a text box of the html file, get the name in a servlet, search for the name in the database and inform the user whether or not the name is in the database.

The database is MySQL and consists of two tables; tableA has three names entered into it via insert when the table was created, John Doe, Jane Doe, and David Paterson. TableB is used for the name being searched (whatever is entered in the text field of the HTML). If the name is found a question mark is inserted followed by the name. If it is not found an exclamation mark followed by the name. For example the name: David Doe is not in tableA therefore !David Doe is inserted in tableB. But for John Doe ?John Doe is inserted in tableB. The applet is then using tableB to display a message telling whether the name is (or is not) in tableA.

It's fairly convoluted. You enter a name in the HTML text field and click submit; that takes you to a servlet that displays the message/link "Click here to see the applet". When you click the link it displays another page that says, for example, "John Doe is in the table".

I have that all working correctly. Now the last step that I can't seem to get to work is to have that applet message "John Doe is in the table" display in a green oval w/white text, or if the name is not one of those three names in tableA the message should display in a red oval with black text. It just continues to display as regular text on a plain white background.

I am including the applet code only, does anyone see what I have done wrong? I wrote the same code as a standalone applet just to see if I could get a message to display in a green oval with white text and it worked fine, so I'm not sure if it's where I'm placing the code. BTW, this professor is unhelpful I have asked him for advice but as an on-line student it's hard to pin him down and I'm quite new to Java.

The Applet code:

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);
    }
  }
}
有帮助吗?

解决方案

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top