Reputation: 593
I am experienced programmer, but never used Java until recently. I have a class that works by copying code from the internet(huzzah), and the Jframe runs in its own thread when I run the code below as its own thread when using the main() function.
But I have a problem. I want to use this Jframe as the interactive portion of another thread (as a private member of a implements Runnable class). AND I want them to interactive. The Jframe method actionPerformed needs to call the parent thread object's functions (I type a command, it does something) AND parent needs to call the .append() method to report the result to the Jframe. I can include a reference to the parent inside my Jframe, so I can call its methods.
So my problem is about designing this properly for thread synchronization. I am not sure how thread synchronization and the eventhandler interact, so as my thread can use the not threadsafe Jframe properly.
Where and how do I initialize the Jframe properly? (Specifically, am I supposed to use the EventQueue in some way?) Or am I missing something glaring and doing this the completely wrong way?
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ActionMapUIResource;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
public class CmdPrompt3 extends JFrame {
private static final String progname = "CmdPrompt <Monitor Game Client>";
private JTextField input;
private JTextArea history;
private JPanel mainpanel;
private JMenuBar greenMenuBar;
private String lastCmd;
private boolean unusedCmd;
//public boolean defaultConstruct = true;
public CmdPrompt3(int x, int y, String name) { //offset coordinates
super("CmdPrompt3 <" + name + ">");
lastCmd = "";
unusedCmd = false;
//defaultConstruct = false;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create the menu bar. Make it have a green background.
greenMenuBar = new JMenuBar();
greenMenuBar.setOpaque(true);
greenMenuBar.setBackground(new Color(154, 165, 127));
greenMenuBar.setPreferredSize(new Dimension(200, 20));
this.setJMenuBar(greenMenuBar);
mainpanel = new JPanel(new BorderLayout());
mainpanel.setBorder(new EmptyBorder(2, 3, 2, 3));
// adjust numbers for a bigger default area
JTextArea history = new JTextArea(25, 40); //25 lines, 40 columns
Font font = new Font(
Font.MONOSPACED,
Font.PLAIN,
16); //font size 16
//history.getFont().getSize()+4);
mainpanel.setFont(font);
history.setFont(font);
mainpanel.add(new JScrollPane(history,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
this.add(mainpanel);
input = new JTextField(80);
input.setFont(font);
this.add(input, BorderLayout.SOUTH);
ActionMap actionMap = new ActionMapUIResource();
actionMap.put("enter", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = input.getText();
//String sofar = history.getText ();
history.append("\tinput box>>\t" + cmd + "\n");
//DO IMPORTANT STUFF HERE
//Set flags for retrieving commands
lastCmd = cmd;
unusedCmd = true;
//clear input line
input.setText("");
}
});
InputMap keyMap = new ComponentInputMap(input);
keyMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
SwingUtilities.replaceUIActionMap(input, actionMap);
SwingUtilities.replaceUIInputMap(input, JComponent.WHEN_IN_FOCUSED_WINDOW, keyMap);
setLocation(x, y);
this.pack();
setVisible(true);
}
//owner thread writes history to window
//TODO this doesn't work when Client calls the function
//Apparently,
public void append(String S) {
history.append(S);
return;
}
//owner thread gets last issued command, if any
public String getUnusedCmd() {
if (unusedCmd) {
unusedCmd = false;
} else {
lastCmd = "";
}
return lastCmd;
}
public static void main(final String args[]) {
Runnable runner = new Runnable() {
public void run() {
new CmdPrompt3(100, 100, "Basic Class Test");
}
};
EventQueue.invokeLater(runner);
}
}
Upvotes: 0
Views: 701