JAR Bundler using OSXAdapter causing application to lag or terminate
After doing it, I'm not fully convinced a SwingWorker is a simpler (aka: better) solution - still requires additional thread synching (between the worker thread and the "outer" thread which passes in the file/names). Anyway (taking the opportunity to learn, and be it by errors :), below is a crude proof of concept example for the basic idea:
- implement the Controller as SwingWorker, which funnels the input from the outer thread into the EDT
- make it accept input (from the adapter, f.i.) via a method doWork(..) which queues the input for publishing
- implement doInBackground to succesively publish the input
open issues
- synch the access to the local list (not an expert in concurrency, but pretty sure that needs to be done)
- reliably detecting the end of the outer thread (here simply stops when the input queue is empty)
Feedback welcome :-)
public class GUI {
private JFrame frame = new JFrame();
private DefaultTableModel model = new DefaultTableModel();
private JTable table = new JTable(model);
private JScrollPane pane = new JScrollPane(table);
public GUI() {
model.addColumn("Name");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}
public void addRow(String name) {
model.addRow(new Object[] { name });
}
/**
* Controller is a SwingWorker.
*/
public static class Controller extends SwingWorker<Void, String> {
private GUI gui;
private List<String> pending;
public Controller() {
gui = new GUI();
}
public void doWork(String newLine) {
if (pending == null) {
pending = new ArrayList<String>();
pending.add(newLine);
execute();
} else {
pending.add(newLine);
}
}
@Override
protected Void doInBackground() throws Exception {
while (pending.size() > 0) {
publish(pending.remove(0));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
/**
* @inherited <p>
*/
@Override
protected void process(List<String> chunks) {
for (String object : chunks) {
gui.addRow(object);
}
}
}
/**
* Simulating the adapter.
*
* Obviously, the real-thingy wouldn't have a reference
* to the controller, but message the doWork refectively
*/
public static class Adapter implements Runnable {
Controller controller;
public Adapter(Controller controller) {
this.controller = controller;
}
@Override
public void run() {
for (int i=0; i<10; i++)
{
controller.doWork("Line "+(i+1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
System.err.println("Initializing controller");
new Adapter(new Controller()).run();
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(GUI.class.getName());
}
How do I pass a file as argument to my Java application created using JAR Bundler?
I've used OSXAdapter
for preferences, about, and quit functionality. You might be able to leverage it's introspective approach to avoid the restriction. As com.apple.eawt.ApplicationListener
is deprecated, you might try com.apple.eawt.OpenFilesHandler
instead.
JAR bundler not found in MAC PC after installing JDK
Solution:
The solution of this problem can be found in the following link. Apparently, Apple has discontinued the existence of JAR bundler.
AbstractTableModel updating from different threads
expect using
SwingWorker
.
I too would expect to use a SwingWorker
, but you may have meant except SwingWorker
.
The best practice is to update the TableModel
on the event dispatch thread as shown here in the process()
implementation of JDBCWorker
, a subclass of SwingWorker
.
Alternatively, you can update the table's model using EventQueue.invokeLater()
, as shown here, but the approach is tedious and error prone. See the comments for details.
Interacting with JTable which is rapidly updated with new rows
I don't think inserting rows in a table changes the selection, so as long as you are updating the TableModel on the EDT, the selected row is still same when the user shows the popup and chooses and action from the popup.
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class TestJTableInsert {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final DefaultTableModel model = new DefaultTableModel(0, 1);
new Timer(500, new ActionListener() {
private final Random random = new Random();
private int data = 1;
@Override
public void actionPerformed(ActionEvent e) {
model.insertRow(random.nextInt(model.getRowCount() + 1),
new Object[] { data++ });
}
}).start();
final JTable table = new JTable(model);
JPopupMenu popup = new JPopupMenu();
popup.add(new AbstractAction("Which row is this?") {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(table,
"This is row " + table.getValueAt(table.getSelectedRow(), 0));
}
});
table.setComponentPopupMenu(popup);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Related Topics
How to Convert Java String into Byte[]
Why Is Hibernate Open Session in View Considered a Bad Practice
Spring Boot and Multiple External Configuration Files
How to Specify the Java Compiler Version in a Pom.Xml File
How to Programmatically Download a Webpage in Java
Can Overridden Methods Differ in Return Type
What Does the Arrow Operator, '->', Do in Java
Output in a Table Format in Java's System.Out
Executorservice That Interrupts Tasks After a Timeout
How Does Cloneable Work in Java and How to Use It
Initialising a Multidimensional Array in Java
Convert Date/Time for Given Timezone - Java
Why Does the Tostring Method in Java Not Seem to Work for an Array
Dynamically Add Components to a Jdialog
Jsoup Java HTML Parser:Executing JavaScript Events