I have a form for the user to fill out in a JFrame which then writes the collected data to a JTable in a different class.
I'm trying to configure it that when the user selects "Submit" that the JFrame will close, but not close down the program. What would be the command I need to achieve this?
The code for the submit button is as follows is as follows:
JButton bMark = new JButton("Submit");
bMark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String start = tbStart.getText();
String end = tbEnd.getText();
String[] marking = {start, end, active, body, dysk, trem, brady};
//This is just for me to ensure the collected data is correct
System.out.println(marking[0] + " " +marking[1] + " " +marking[2] + " " +
marking[3] + " " + marking[4] + " " + marking[5] + " " + marking[6]);
//This is is the class the form data is being sent to
markTable.main(marking);
//This is where I would like the close the current window
}
});
bMark.setBounds(308, 191, 86, 23);
The class name is createMark and the method is public createMark
Thanks to anyone who replies,
Jared.
//This is where I would like the close the current window
there are these ways
JFrame#setVisible(false), but not terminating current JVM, this session exist until PC restarted,
JFrame#dispose() terminating current JVM,
System#exit(int); terminating current JVM,
better would be to JFrame#setDefaultCloseOperation
don't suplly JOptionPane, maybe will be better use that directly
You need to set the default close operation on the JFrame as such:
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
This will take care of the case where the user closes the window using the title bar or hits something like Alt+F4.
Next, simply call setVisible(false) when the submit button is pressed.
Related
I've written a rather simple method for my paper/spigot Minecraft server plugin that detects potential lag machines under construction.
The issue I have is that I want to send a single chat message that, when clicked once, will first run a /vanish command on behalf of the clicker.
Then if (and only if) the vanish was successful, I want to run a teleport command to a location included along with the specific instance of the ClickEvent.
Both of those commands need to be completed from the single user click event.
For reference here is the method that calls notifyOps() and includes the TextComponent in question, msg
if (LagMats.contains(blockType) || mat.contains("MINECART") || mat.contains("DOOR")) {
int counter = 0;
for (Material thisMat: LagMats) {
if (thisMat != Material.GRAVEL) {
counter += Utilities.blockCounter(block.getChunk(), thisMat);
}
}
TextComponent warn = new TextComponent("WARN "); warn.setBold(true);
warn.setColor(ChatColor.RED);
TextComponent msg = new TextComponent("Potential lag-machine at " +
block.getX() + ", " + block.getY() + ", " + block.getZ() + " in " + dimension +
" by " + placer_name + " with UUID: " + placer.getUniqueId());
String cmd = "/execute in " + env + " run tp #s " +
block.getX() + " " + block.getY() + " " + block.getZ();
msg.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
if (counter > 256) {
Utilities.notifyOps(new TextComponent(warn, msg));
}
}
Oh and the actual little code of notifyOps where the TextComponent is used in a message:
// send a message to all online ops and console
public static boolean notifyOps(TextComponent msg) {
if (msg == null) return false;
for (Player thisPlayer: Bukkit.getOnlinePlayers()) {
try {
if (thisPlayer.isOp()) thisPlayer.spigot().sendMessage(msg);
} catch (Exception e) {return false;}
}
System.out.println(msg.getText());
return true;
}
So I want to have the user click just once, run two commands, the second only if the first succeeds, and would be best if it could be done within the try block the message is sent from.
I could write a custom command for this purpose, and then just run that command, but I rather avoid adding classes for such a small addition if it's actually possible and I just have no idea.
Thanks for any advice or help!
There is no way of doing that without writing a custom command...
This is impossible because the ClickEvent and HoverEvent are entirely client-side. That means that there are no packets sent from the Player to the server. Therefore, it is impossible to callback the click of the Player and call a method to perform what you are trying to do.
You may notice that all the ClickEvent.Actions do not affect the server. OPEN_URL, OPEN_FILE, RUN_COMMAND, SUGGEST_COMMAND, CHANGE_PAGE and COPY_TO_CLIPBOARD are all actions taken on the client-side.
The only way here is to make the client send a command to the server which will trigger a method.
I'm working on a program that serves as a hypothetical email system in which users can be created and can send messages to other users that have been created.
The message will be stored in a "Message" class, and the text is typed in a JTextArea in a GUI. What I want to know is how I would go about storing the text typed into the JTextArea, in the exact same layout (indentations and all), within the Message class. I thought about text files but then there would have to be one for each message, potentially creating an infinite number of them, and I don't like the concept of having to make a system for coming up with unique names for each text file.
Can you please give me some advice?
Simply implement the DocumentListener interface, then do the following:
JTextArea someMessage = new JTextArea();
someMessage.getDocument().addDocumentListener(new MyDocumentListener());
someMessage.getDocument().putProperty("name", "Text Area");
Here, we assume the name of the listener you implement is called MyDocumentListener, and the implementation could be as simple as:
class MyDocumentListener implements DocumentListener {
String newline = "\n";
#Override
public void insertUpdate(DocumentEvent e) {
updateLog(e, "inserted into");
}
#Override
public void removeUpdate(DocumentEvent e) {
updateLog(e, "removed from");
}
#Override
public void changedUpdate(DocumentEvent e) {
//Plain text components do not fire these events
}
public void updateLog(DocumentEvent e, String action) {
Document doc = (Document)e.getDocument();
int changeLength = e.getLength();
displayArea.append(
changeLength + " character" +
((changeLength == 1) ? " " : "s ") +
action + doc.getProperty("name") + "." + newline +
" Text length = " + doc.getLength() + newline);
}
}
Examples taken from Oracle website. I recommend reading the rest of that article as it goes into much depth of how to effectively listen for updates to the internal document model.
How to get text that was inserted
insertUpdate is what notifies you when new text has been typed into the textarea. You can get the freshly inserted text by calling off to the DocumentEvent#getOffset and DocumentEvent#getLength. Using both methods, you can get the offset (index) within document where the insertion happened, as well as the length of the change.
Then to get the actual text that was inserted, you call DocumentEvent#getDocument#getText and supplying the offset and length you got from the event.
How to get all the text in the textarea
You can use this similar method to get the entire text in the document by making use of Document#getStartPosition and Document#getEndPosition, then calling Document#getText.
Or even easier, JTextArea#getText
I'm working on a application which takes pizza orders. Once the user clicks the order summary button the program would display the order summary. The application looks like this:
I would like to print out the order summary(only not the error) in a new penal with a JTextArea like such:
But I don't know how. This is what my application displays right now:
Here is the Code related to the display:
orderSummary = "Customer Name: " + name +
"\nPhone Number: " + phoneNumber +
"\nSize: " + size +
"\nToppings: " + toppings +
"\nTotal: $" + total;
if(error)
JOptionPane.showMessageDialog(null, ErrorString);
else
JOptionPane.showMessageDialog(null, orderSummary);
Error display:
I'm not 100% sure of what you are asking, but if you are looking for a dialog to popup (not just a panel), then you could try something like:
JDialog zMessageDialog = new JDialog((java.awt.Frame) null, true);
zMessageDialog.setTitle("Order summary");
zMessageDialog.setLayout(new BorderLayout());
JTextArea zTextArea = new JTextArea("Blah blah\nblah blah\nblah blah");
zTextArea.setEditable(false);
zTextArea.setColumns(40);
zTextArea.setRows(10);
zTextArea.setBackground(null);
JScrollPane zScrollPane = new JScrollPane(zTextArea);
zMessageDialog.add(zScrollPane, BorderLayout.CENTER);
zMessageDialog.revalidate();
zMessageDialog.pack();
zMessageDialog.setVisible(true);
This just puts a JTextArea in a JDialog. It makes the JTextArea non-editable, and sets its background color to null (which makes it look less editable).
Of course, this may not be the best way to go in terms of a user interface, but that is a different question. If you are using an IDE like Netbeans, you can easily create a separate class based on JDialog and add a panel at the bottom with an "OK" button, and whatever other customizations you desire.
I posted this code yesterday for another issue but now I once again must call on you all for help.. I appreciate all the assistance so far I have had without this community I wouldn't have made it so far.
Now, my problem is quite simple. I have a GUI with an input box for the user and three buttons. The buttons are not JButtons, they are the standard JOptionsPane yes, no, and cancel buttons. I did change the text to "next entry", "next batch", and "finished".
Before I made changes to my GUI I had standard buttons. The button that will most often be used is the "yes" button (now "next entry").. This button will be clicked a LOT in my program. Before the default button setting worked.. A user could simply type a number and press enter quickly. Now the enter key will not activate the default button instead the user must physically click on it.. This is what I want to change.
Is there any way I can set the below code so when the user clicks enter, regardless of what text they have typed, the "yes" (now "next batch" is clicked on default)? For what it's worth I did do research on this but could not find a solution that suited my specific circumstances.
package nacha;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Testing4
{
public static void main(String args[]){
String css = "<span style='font-size:10; color: white; background-color:black'>";
String batchCss = "<span style='font-size: 20'>";
String endSpanCss = "</span>";
String table = "<table border=4>";
String endTable = "</table>";
String mainCss = "<span style='font-size:12; color: red'>";
String header1Css = "<span style = 'font-size:15; font-weight:bold;text-decoration:underline;border:1px dotted red'>";
String text1Css = "<span style = 'font-size:12; font-style:italic'>";
String text = "<html>" +
css + batchCss + "1 of 2"+endSpanCss+endSpanCss+ endSpanCss +
"<br><br><br>"+header1Css+"Entry Detail:"+endSpanCss +
"<br>"+mainCss+"111111111111111111111"+endSpanCss+
"<br><br><br>"+text1Css+"Please type 1-21 to apply a reason code and addenda record to the entry detail." +
"<br>Please type 'h' and press the next entry button to open the help screen."+endSpanCss +
"<br><br><br>"+header1Css+"Reason Codes"+ endSpanCss +
"<br>"+table+"R01 - Insufficient Funds" +
"<br>R02 - Account Closed" +
"<br>R03 - No Account" +
"<br>R04 - Invalid Account Number" +
"<br>R05 - Unauthorized Debit to Consumer Account" +
"<br>R06 - Returned per ODFI Request" +
"<br>R07 - Auth Revoked by Customer" +
"<br>R08 - Payment Stopped" +
"<br>R09 - Uncollected Funds" +
"<br>R10 - Customer Advises Not Authorized" +
"<br>R11 - Check Truncation Entry Return" +
"<br>R12 - Branch Sold to Another DFI" +
"<br>R13 - Invalid ACH Routing Number" +
"<br>R14 - Represenative Payee Deceased or Unable to Continue" +
"<br>R15 - Beneficiary or Account Holder Deceased" +
"<br>R16 - Account Frozen" +
"<br>R17 - File Record Edit Criteria" +
"<br>R18 - Improper Effective Entry Date" +
"<br>R19 - Account Field Error" +
"<br>R20 - Non-Transaction Amount" +
"<br>R21 - Invalid Company Information" +
"<br>R22 - Invalid Individual ID Number"+endTable;
//Below code creates the GUI for the return builder portion of the program.
Object[] options1 = {"Next Entry","Next Batch","Finished"};//Changes the default buttons.
BorderLayout border = new BorderLayout();
JPanel panel = new JPanel();
panel.setLayout(border);
panel.add(new JLabel(text),BorderLayout.NORTH);//Adds the label to the top of the panel.
JTextField textField = new JTextField(10);
panel.add(textField,BorderLayout.SOUTH);//Adds a user-input text area to the bottom of the panel.
int result = JOptionPane.showOptionDialog(null, panel, "Return Builder", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options1, JOptionPane.YES_OPTION);
}
}
You need to pass the default option as the final argument to JOptionPane.showOptionDialog:
int result = JOptionPane.showOptionDialog(null, panel, "Return Builder",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options1, options1[0]);
This will have the side effect of making that button have the initial keyboard focus whenever the dialog is displayed. If you don't want that, you can force the JTextField to receive the focus whenever it is displayed in a window:
textField.addHierarchyListener(new HierarchyListener() {
#Override
public void hierarchyChanged(HierarchyEvent e) {
final Component c = e.getComponent();
long flags = e.getChangeFlags();
if ((flags & HierarchyEvent.SHOWING_CHANGED) != 0 &&
c.isShowing()) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
c.requestFocusInWindow();
}
});
}
}
});
A side note: For asking the user to select from a list of known options, a JComboBox is a better choice than a JTextField. Your Help option can simply be a different JButton, present in the message body of the JOptionPane.
I am having some trouble with a couple of methods in my program: I have a method that is called when the user clicks a start button on the GUI. This method will receive all of the network traffic currently being sent/ received over the network, and display information about it to the user. The user can stop this method being called by clicking the stop button.
This method currently looks like this:
public static void retrieveFilteredPdu(){
/*Try/Catch block copied from 'receivePdu()' method in EspduReceiver.java on 07/05/2014
* Now edit it so that it will receive all PDUs, but only display the ones matching the filter values in the top JTextArea */
try{
/*Specify the socket to receive the data */
EspduReceiver.socket = new MulticastSocket(EspduSender.PORT);
EspduReceiver.address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
EspduReceiver.socket.joinGroup(EspduReceiver.address);
//stopCapture = false;
/*Loop infinitely, receiving datagrams */
while(true){
/*First, set the value of the 'stopCapture' boolean to 'false', in case it has previously been set to true during the life of
* the program */
/*stopCapture = false; /*For some reason, if I do this here, clicking the 'Get site' button causes the program to start receiving
PDUs again, and you are not able to stop it without manually shutting down the program. Possibly because I am infinitely
setting the value of 'stopCapture' to false?*/
byte buffer[] = new byte[EspduReceiver.MAX_PDU_SIZE];
EspduReceiver.packet = new DatagramPacket(buffer, buffer.length);
EspduReceiver.socket.receive(EspduReceiver.packet);
Pdu pdu = EspduReceiver.pduFactory.createPdu(EspduReceiver.packet.getData()); /*Moved this line to the top of the class to declare as global variable (29/04/2014) */
if(pdu != null){
System.out.print("Got PDU of type: " + pdu.getClass().getName());
if(pdu instanceof EntityStatePdu){
EntityID eid = ((EntityStatePdu)pdu).getEntityID();
Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
System.out.println(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
System.out.println("Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "] ");
/*Add PDU to ArrayList of PDUs */
EspduReceiver.espdu.add(pdu);
/* System.out.println(" PDU added to arrayList. ");
System.out.println(espdu); /*This is printing out the actual DIS messages (i.e. edu.nps.moves.dis.EntityState...),
maybe try adding the 'eid.getSite()', etc to an ArrayList instead. Use Associative arrays/ map/ hashmap */
EspduReceiver.entitySite.add(eid.getSite());
System.out.println("Entity Site added to ArrayList from Filter.retrieveFilteredPdu() ");
EspduReceiver.entityApplication.add(eid.getApplication());
System.out.println("Entity Application added to ArrayLIst. ");
EspduReceiver.entity.add(eid.getEntity());
System.out.println("Entity ID added to ArrayList");
/*Check that everything is actually in the ArrayLists
for(int i : entity){ /*Substituted 'entity' with 'entitySite' and 'entityApplication'- values are all printed correctly.
System.out.println(i);
} */
/*07/05/2014
* Write a method that will only append the PDUs that match the filter values to the text area,
* call that method here. */
/*Now append each PDU to the text area */
Gui.displayFilteredOutput.append("\n");
Gui.displayFilteredOutput.append("EID: [" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "]. ");
Gui.displayFilteredOutput.append("Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "] ");
/*Append every PDU that matches the filter criteria to the displayFilteredOutput JTextArea
Gui.displayFilteredOutput.append("\n");
Gui.displayFilteredOutput.append("EID: [" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "]. ");
Gui.displayFilteredOutput.append("Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "] "); */
} else if(!(pdu instanceof EntityStatePdu)){
System.out.println("There are no PDUs currently being received.");
}
System.out.println();
}
Thread.sleep(1000);
/*Try adding a boolean to allow me to stop the capture by clicking 'stop' button- Look on stackoverflow */
boolean queryStopCapture = EspduReceiver.stopCapture;
if(queryStopCapture == true){
System.out.println("Break clause in 'queryStopCapture' if statement in EspduReceiver.java has been called. ");
break; /*Use a call to receivePdu() to populate the second JTextArea, but don't let it call a 'break' clause at all.
* Find some other way of adding a 'break' to the output displayed in the first JTextArea (01/05/2014)
* Maybe add this code to receivePdu() call in ActionListener instead of here.
*/
}
} /*end while */
} /*end try */
catch(Exception e){
System.out.println(e);
e.printStackTrace();
System.out.println("Error in retrieveFilteredPdu() method. ");
/*09/04/2014 # 17:100
* If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
* that pdu does not actually hold a packet. */
}
}
I have another method, which, in theory, should display information about only the network traffic which has attributes matching some values set by the user. This method is called when the user clicks the 'Filter' button on the GUI. The method currently looks like this:
public static void filterPDUs(){
// if(EspduReceiver.startCapture == true){
/*If EspduReceiver.startCapture is true, then the program is already receiving PDUs, so now I need to set it to only display the ones that
* match the filter criteria. Do this by checking the PDU attributes against the filter values before printing- if they match, then print,
* if not, don't. */
if((EspduReceiver.startCapture == true) && (EspduReceiver.stopCapture == false)){
/*Get the size of the sitesToBeFiltered ArrayList, and store in a variable. Will need to update the variable with every iteration
* of the loop, because the ArrayList will keep growing as long as the capture is running. */
int sitesToBeFilteredSize = sitesToBeFiltered.size();
int matchingSitesIterator = 0;
/*First, check if site filter value matches the PDU's site, if it does, then check Application, if it matches again, then check ID.
* If at any point it doesn't match, exit the while loop. */
while(matchingSitesIterator < sitesToBeFilteredSize){
System.out.println("SitesToBeFiltered.size() = " + sitesToBeFilteredSize);
if(sitesToBeFiltered.get(matchingSitesIterator) == Filter.filter1Value){
if(applicationsToBeFiltered.get(matchingSitesIterator) == Filter.filter2Value){
if(IDsToBeFiltered.get(matchingSitesIterator) == Filter.filter3Value){
Gui.displayFilteredOutput.append("Matching PDU found: [" + sitesToBeFiltered.get(matchingSitesIterator) + ", " + applicationsToBeFiltered.get(matchingSitesIterator) + ", " + IDsToBeFiltered.get(matchingSitesIterator) + "] ");
} else {Gui.displayFilteredOutput.append("Sorry, there were no PDUs found with the specified ID value.");}
Gui.displayFilteredOutput.append("Need to display every PDU that had a matching Site & Application here. ");
}else {Gui.displayFilteredOutput.append("Sorry, there were no PDUs found with the specified Application value.");}
Gui.displayFilteredOutput.append("need to display every PDU that had a matching Site here. ");
}else {Gui.displayOutput.append("Sorry, there were no PDUs found with the specified Site value.");}
}
} else {
Gui.displayFilteredOutput.append("Do something if EspduReceiver.startCapture is not true, and EspduReceiver.stopCapture is not false");
}
// }else if(EspduReceiver.startCapture == false){
/*If EspduReceiver.startCapture is false, then the program is not receiving PDUs, so I now need to call the method that will receive PDUs,
* and display only the ones that match the filter criteria. */
// }
}
The problem I'm having is that for some reason, if the user clicks the 'Filter' button to display only the PDUs with matching filter criteria, after clicking 'Start' (to call the first method), then the program crashes completely... (i.e. it appears to stop performing the function that it was carrying out, and will not respond to clicks on any buttons or even the 'Close window' button)
If they click 'Filter' after having clicked 'Start' & 'Stop' (i.e. when the first method is not running, then the second method performs its tasks as expected.
It seems that for some reason, calling the second method while the first method is still running causes the program to crash- and I can't work out why this is... can anyone point out what's going wrong here?
Edit
I have the following code in my main method:
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
Gui gui = new Gui();
gui.setVisible(true);
}
});
}
You need to show more of the code, as others have said, but if you're using Swingworkers or other threads to run these methods, then either the methods have to be thread-safe or they need to be synchronized to prevent their execution from being interleaved. If you're directly accessing Swing components outside the event-dispatching thread, then Swing will make demons come out of your nose, so don't do that (there are some special exceptions for some text components, but generally it's prohibited). If you're not sure, stick assert java.awt.EventQueue.isDispatchThread() before every statement that constructs or uses a Swing object, and enable assertions in the runtime system.
I assume Gui is built on Swing. Read the Swing tutorial, and pay attention to the Event Dispatch Thread. I can't see how the Swing portion of you code works, but I'm guessing you are locking up the EDT somehow. A long-running process needs to run in its own thread and use SwingUtilities.invokeLater() to update Swing components, like your text area.