I have a series of Text- and Comboboxes along a jTable. I use the input from the boxes to filter the results of a JPQL-query, which are displayed on the jTable. Now, the idea was to automate the process, so that every time the user types a character in a box, the app sends the query automatically and updates the jTable with the filtered results. I tried doing it like this:
public class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent evt){
setFilters();
displayResults(); }}
setFilters() and displayResults() are the methods that respectively set the parameters and the query and get the ResultList and update the jTable. I then added the keyPressed to all relevant Textboxes, along with some System.out.println lines for debugging. What happens is following: when i enter the first character nothing happens. If i enter a second character the KeyListener works and sends the query, but filters only with the second character, the first one is ignored. That´s my first weirdness. The second one is, looking at my console i realized the query is beeing sent 6 times for every for every succesful Key Listened. Help would be greatly appreciated. On second thought, I´m also inserting my setFilters() and displayResults().
private void setFilters() {
//Auslesen der gesetzten Filter
String name=jName.getText()+"%";
String vorname= jVorname.getText()+"%";
String vvname= jVName.getText()+"%";
String vvorname=jVVorname.getText()+"%";
String mname=jMName.getText()+"%";
String strasse=jAdresse.getText()+"%";
String plz=jPlz.getText()+"%";
String ort=jOrt.getText()+"%";
String gruppe=jGruppe.getText()+"%";
String geschlecht=(String) jGeschlecht.getSelectedItem()+"%";
String mvorname=jMVorname.getText()+"%";
String firma=jFirma.getText()+"%";
//Die Query
kinderQuery = java.beans.Beans.isDesignTime() ? null : rcwPUEntityManager.createQuery("SELECT k FROM Kinder k "
+ "INNER JOIN k.vaeter vat "
+ "INNER JOIN k.muetter mut "
+ "INNER JOIN k.gruppen gru "
+ "INNER JOIN k.firmen fir "
+ "WHERE k.kindName LIKE :name "
+ "AND k.kindVorname LIKE :vorname "
+ "AND vat.vaterName LIKE :vname "
+ "AND vat.vaterVorname LIKE :vvorname "
+ "AND mut.mutterName LIKE :mname "
+ "AND mut.mutterVorname LIKE :mvorname "
+ "AND k.kindStrasse LIKE :strasse "
+ "AND k.kindPLZ LIKE :plz "
+ "AND k.kindOrt LIKE :ort "
+ "AND gru.gruppeName LIKE :gruppe "
+ "AND k.kindGeschlecht LIKE :geschlecht "
+ "AND fir.firmaName LIKE :firma ");
//Einsetzen der ausgelesenen Strings in die JPQL-Query Parameter
kinderQuery.setParameter("name", name);
kinderQuery.setParameter("vorname", vorname);
kinderQuery.setParameter("vname", vvname);
kinderQuery.setParameter("vvorname", vvorname);
kinderQuery.setParameter("mname", mname);
kinderQuery.setParameter("mvorname", mvorname);
kinderQuery.setParameter("strasse", strasse);
kinderQuery.setParameter("plz", plz);
kinderQuery.setParameter("ort", ort);
kinderQuery.setParameter("gruppe", gruppe);
kinderQuery.setParameter("geschlecht", geschlecht);
kinderQuery.setParameter("firma", firma);
}
private void displayResults(){
java.util.Collection data = kinderQuery.getResultList();
System.out.println(data);
kinderList.clear();
kinderList.addAll(data);
jTable1.repaint();
}
Thanks in advance !
The problem is that the Document used by the text field has not been updated when the keyPressed event is generated. You could listen for the keyTyped event, however I don't recommend this as it is not the best solution and Swing provides a better API to use.
The better way to do this is to use a DocumentListener which is specifically designed for this purpose. Read the section from the Swing tutorial on How to Write a Document Listener for an example and explanation.
Here's pretty much how to do it. A couple of benefits for you using this approach instead of the keyPressed is that it will work also when you paste some text into the fields and it's easy to avoid doing all your filtering on deletes etc.
// in your frame or panel
Document doc = new PlainDocument();
doc.addDocumentListener(new MyDocumentListener());
JTextField textField = new JTextField(15);
textField.setDocument(doc);
add(textField);
private class MyDocumentListener implements DocumentListener
{
public void insertUpdate(DocumentEvent documentEvent)
{
// Do your stuff here
System.out.println("insert detected!");
}
public void removeUpdate(DocumentEvent documentEvent)
{
// ignore this
}
public void changedUpdate(DocumentEvent documentEvent)
{
// ignore this
}
}
And to avoid doing search and filter round trips on every weird thing your users might input into the text fields you should consider doing your own implementation of PlainDocument that only accepts certain characters.
private class MyDocument extends PlainDocument
{
#Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
{
StringBuilder builder = new StringBuilder(getText(0, getLength()));
builder.insert(offs, str);
if (builder.toString().matches("[A-Za-z]*"))
{
super.insertString(offs, str, a);
}
}
}
Related
I started Java for plugin codding in minecraft. now I'm trying to add role names as prefix and show it in chat.
ArrayList<String> userRoles = new ArrayList<String>();
if(player.hasPermission("chat.rank.admin")){
userRoles.add("[Admin]");
} if(player.hasPermission("chat.rank.vip")) {
userRoles.add("[VIP]");
}
event.setFormat(userRoles<>(1) + " " + player.getDisplayName() + "§7: " + msg);
// In this line, the expected output is "[Admin] user: msg" or both [Admin] [VIP] user: msg"
// But it gives "([Admin],[VIP]) user: msg"
// I'm sure it has a simple solution but as I said, I'm new here. thanks from now
It seems like you are trying to create a list which only stores one value.
You might want to try creating a function that get the rank name of the player outside of your PlayerChatEvent listener.
Here's a demo code:
public String getPlayerRankName(Player p){
if (p.hasPermission("chat.rank.admin"))
return "[Admin]";
else if (p.hasPermission("chat.rank.vip"))
return "[VIP]";
else
return "";
}
And in your PlayerChatEvent event listener, call this function in your chat line:
event.setFormat(getPlayerRankName(event.getPlayer()) + " " + player.getDisplayName() + "§7: " + msg);
I cannot write in TextArea and I don't know what to do in this case.
Here is my code from class "Server" that is used in order to put text in TA:
public class Server implements Runnable {
.
.
.
#Override
public void run() {
while (true) {
try {
if (queue.size() !=0) {
Task task = queue.take();
String text = "Server" + Integer.toString(getIdServer()) + " is processing the task: " + Integer.toString(task.getIdTask()) + " with proc time " + Integer.toString(task.getProcessingTime());
InputShop.textArea.setText(text);
Thread.sleep(task.getProcessingTime() * 1000);
waitingTime.addAndGet(-task.getProcessingTime());
}
} catch (InterruptedException e) {
}
}
}
public void addTask(Task newTask) {
String text2 = "Task "+ Integer.toString(newTask.getIdTask()) + " arrives at s " + Integer.toString(newTask.getArrivalTime())+ " on server "+ Integer.toString(getIdServer());
InputShop.textArea.setText(text2);
queue.add(newTask);
waitingTime.addAndGet(newTask.getProcessingTime());
}
And my UI Class looks at that part with TextArea like this:
TextArea textArea = new TextArea();
textArea.setPrefWidth(300);
textArea.setPrefHeight(300);
GridPane.setConstraints(textArea, 8, 8);
gridPane.getChildren().add(textArea);
textArea.setEditable(false);
If I write "System.out.println(...);" instead of the part with "InputShot.textArea.setText(...);" everything works fine, and it prints everything on the output log of the screen.
I have been searching a lot and struggling with this problem for hours and I do not know how to manage it, so I would appreciate every help!
If I missed an important part of code, or information, please let me know in order to edit the question!
How can I automatically print without poping up dialog box or automatically accept print dialog? Here is some of my code:
if ("OUT".equals(rs.getString("empattendance"))) {
String date = dft.format(dNow);
String time = tft.format(dNow);
textArea.setText(date + "\n" + "\n" +
fullname +"\n" +
"Time In: " + time + "\n" +
"Status: "+ statusin +
"\n" +
"\n" +
"____________________\n" +
" Sign by Supervisor");
try {
//printing
Boolean complete = textArea.print();
if(complete){
}
else{
}
} catch (PrinterException ex) {
Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
}
and here's the screenshot of the current behaviour.
thanks
When I look at your code I have few thoughts before answer.
1) Do not use String. Better for comparing stuff is Enumerators I believe.
2) If you would like to set text to textArea previously create some method using StringBuilder for example which will be creating the String you would like to set. Joshua Bloch says
Item 15: minimize mutability (...) If a client requires performing expensive multi-stage operations on your class, expose them as primitive methods, or provide a mutable companion class (like StringBuilder for String).
And take a look at this topic for more.
3) To print data from textArea if I were you I would try to use this.
I believe that would help you
(I'm jumping from Esper to Siddhi)
I'm trying to deploy several queries in the same stream. The example here https://docs.wso2.com/display/CEP400/Using+Siddhi+as+a+Library shows how to deploy a query in a stream, altogether in one ExecutionPlan. So what if I want to add a query to the same execution plan, o same stream?
I'm interest to do this grammatically, Java code.
UPDATE
I want to add queries in an existing execution plan. This means while streams are arriving, and not before.
Using an example posted as answer:
SiddhiManager siddhiManager = new SiddhiManager();
String executionPlan = "" +
"#Plan:name('demo') " +
"" +
"define stream cseEventStream (symbol string, price float, volume long);" +
"" +
"from cseEventStream[symbol==\"WSO2\"] " +
"insert into wso2Stream;" +
"" +
"from cseEventStream[symbol==\"ABC\"] " +
"insert into abcStream;";
ExecutionPlanRuntime executionPlanRuntime = siddhiManager.createExecutionPlanRuntime(executionPlan);
StreamCallback streamCallback = new StreamCallback() {
#Override
public void receive(Event[] events) {
EventPrinter.print(events);
}
};
executionPlanRuntime.addCallback("wso2Stream", streamCallback);
//Similarly, we can add another call back for abcStream
streamCallback.startProcessing();
InputHandler inputHandler = executionPlanRuntime.getInputHandler("cseEventStream");
executionPlanRuntime.start();
// HERE: ADD new query <---------------------------------------------
inputHandler.send(new Object[]{"WSO2", 700f, 100l});
inputHandler.send(new Object[]{"ABC", 60.5f, 200l});
inputHandler.send(new Object[]{"WSO2", 60.5f, 200l});
streamCallback.stopProcessing();
executionPlanRuntime.shutdown();
Following sample adds multiple Queries, for same Stream (cseEventStream), within the same Execution Plan.
SiddhiManager siddhiManager = new SiddhiManager();
String executionPlan = "" +
"#Plan:name('demo') " +
"" +
"define stream cseEventStream (symbol string, price float, volume long);" +
"" +
"from cseEventStream[symbol==\"WSO2\"] " +
"insert into wso2Stream;" +
"" +
"from cseEventStream[symbol==\"ABC\"] " +
"insert into abcStream;";
ExecutionPlanRuntime executionPlanRuntime = siddhiManager.createExecutionPlanRuntime(executionPlan);
StreamCallback streamCallback = new StreamCallback() {
#Override
public void receive(Event[] events) {
EventPrinter.print(events);
}
};
executionPlanRuntime.addCallback("wso2Stream", streamCallback);
//Similarly, we can add another call back for abcStream
streamCallback.startProcessing();
InputHandler inputHandler = executionPlanRuntime.getInputHandler("cseEventStream");
executionPlanRuntime.start();
inputHandler.send(new Object[]{"WSO2", 700f, 100l});
inputHandler.send(new Object[]{"ABC", 60.5f, 200l});
inputHandler.send(new Object[]{"WSO2", 60.5f, 200l});
streamCallback.stopProcessing();
executionPlanRuntime.shutdown();
I've used Siddhi version 3.0.6-beta2.
This code sample is a modification made to one of the Siddhi Passthrough test cases (PassThroughTest4).
Update:
Looking at ExecutionPlanRuntime class, it does not seem like it is possible to add queries "on the run".
So, to my understanding, you will have to shutdown current execution plan runtime, add those new queries and start it back.
I want to make a student data that saved into textfile by bufferedwriter (i've finish this part) but i also want to make update part so i make the other JForm
here is the code :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
String SID = atf.getText();
String FN = btf.getText();
String LN = ltf.getText();
String CN = ctf.getText();
String EM = etf.getText();
String CarNum = cartf.getText();
Calendar cal =Calendar.getInstance();
try{
FileWriter file = new FileWriter("asd.txt");
BufferedWriter buffer = new BufferedWriter(file);
buffer.write("Student ID : " + SID);
buffer.newLine();
buffer.write("First Name : " + FN);
buffer.newLine();
buffer.write("Last Name : " + LN);
buffer.newLine();
buffer.write("Contact Number : " + CN);
buffer.newLine();
buffer.write("Email : " + EM);
buffer.newLine();
buffer.write("Car Number : " + CarNum);
buffer.newLine();
buffer.write("Date Of Registration : " + cal.getTime());
buffer.close();
}
catch(IOException e){
// TODO add your handling code here:
}
JOptionPane.showMessageDialog(null, "Data has been saved");
dispose();
}
and after all , i want to make another method with JTextField
here is the code
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String NSID=NSIDx.getText();
String NFN=NFNx.getText();
String NLN=NLNx.getText();
String NC=NCNx.getText();
String NE=NEx.getText();
String NCarNum=NCarNumx.getText();}
i want to input the second code to update the first code that means i must change the value of SID become NSID
i dont know how to use private method in other private method . is it possible ?
best you use xml file to store the data.
so you can construct a structure for your data and using parsers can easily update,insert, delete also possible.
Yes, it is possible to call a private method from another private method. The notion of privacy is only for the users of the object and is not applicable for methods in the object itself. By the way, since the code is similar in both these methods, you should separate it out in another private method and call that method from these two event handlers.