The toolbar runaway from expected result the first button suppose located at the last button.. the rest of the button suppose display below the menu bar, this happening while change the eclipse version and currently i am using
eclipse luna 4.4.2
this line seem not helping
IToolBarManager toolbar = new ToolBarManager(SWT.FLAT | SWT.LEFT);
In eclipse 3.7 those functions like openWorkbenchWindow (Workbench.class), restoreWorkbenchWindow will be call and end up to function like arrangeToolbar will be trigger
/*
* (non-Javadoc) Method declared on IWorkbench.
*/
public IWorkbenchWindow openWorkbenchWindow(final String perspID,
final IAdaptable input) throws WorkbenchException {
// Run op in busy cursor.
final Object[] result = new Object[1];
BusyIndicator.showWhile(null, new Runnable() {
public void run() {
try {
result[0] = busyOpenWorkbenchWindow(perspID, input);
} catch (WorkbenchException e) {
result[0] = e;
}
}
});
if (result[0] instanceof IWorkbenchWindow) {
return (IWorkbenchWindow) result[0];
} else if (result[0] instanceof WorkbenchException) {
throw (WorkbenchException) result[0];
} else {
throw new WorkbenchException(
WorkbenchMessages.Abnormal_Workbench_Conditi);
}
}
/*
* (non-Javadoc)
*
* #see org.eclipse.ui.IWorkbench#restoreWorkbenchWindow(org.eclipse.ui.IMemento)
*/
IWorkbenchWindow restoreWorkbenchWindow(IMemento memento)
throws WorkbenchException {
WorkbenchWindow newWindow = newWorkbenchWindow();
newWindow.create();
windowManager.add(newWindow);
// whether the window was opened
boolean opened = false;
try {
newWindow.restoreState(memento, null);
newWindow.fireWindowRestored();
newWindow.open();
opened = true;
} finally {
if (!opened) {
newWindow.close();
}
}
return newWindow;
}
void updatePerspectiveBar() {
// Update each item as the text may have to be shortened.
IContributionItem[] items = perspectiveBar.getItems();
for (int i = 0; i < items.length; i++) {
items[i].update();
}
// make sure the selected item is visible
perspectiveBar.arrangeToolbar();
setCoolItemSize(coolItem);
perspectiveBar.getControl().redraw();
if (getControl() != null)
getControl().pack(true);
}
however, eclipse 4.4.2 does not contains above functions anymore
the functions contents are different and restoreWorkbenchWindow are no longer support.
/*
* (non-Javadoc) Method declared on IWorkbench.
*/
#Override
public IWorkbenchWindow openWorkbenchWindow(String perspectiveId, IAdaptable input)
throws WorkbenchException {
IPerspectiveDescriptor descriptor = getPerspectiveRegistry().findPerspectiveWithId(
perspectiveId);
try {
MWindow window = BasicFactoryImpl.eINSTANCE.createTrimmedWindow();
return openWorkbenchWindow(input, descriptor, window, true);
} catch (InjectionException e) {
throw new WorkbenchException(e.getMessage(), e);
}
}
public WorkbenchWindow openWorkbenchWindow(IAdaptable input, IPerspectiveDescriptor descriptor,
MWindow window, boolean newWindow) {
return (WorkbenchWindow) createWorkbenchWindow(input, descriptor, window, newWindow);
}
any advise or way to fix the issues i am facing? thanks you.
Related
I'm using the current version of SWT to build my applications and I want to run it under Mac OS X (Yosemite).
My problem is now that I'm not be able to capture clicks on the "About", "Preferences" and "Quit" menu items which were automatically added to my application.
I already searched a lot and found the following class which seems very helpful to me http://www.transparentech.com/files/CocoaUIEnhancer.java.
And that's my code to initialize it:
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class Test {
private Display display;
private Shell shell;
public Test(Display display) {
this.display = display;
initUI();
}
public void open() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private void initUI() {
shell = new Shell(display);
shell.setSize(808, 599);
shell.setText("Test");
AboutHandler aboutHandler = new AboutHandler();
PreferencesHandler preferencesHandler = new PreferencesHandler();
QuitHandler quitHandler = new QuitHandler();
CocoaUIEnhancer uienhancer = new CocoaUIEnhancer("Test");
uienhancer.hookApplicationMenu(display, quitHandler, aboutHandler, preferencesHandler);
}
private class AboutHandler implements Listener {
public void handleEvent(Event e) {
}
}
private class PreferencesHandler implements Listener {
public void handleEvent(Event e) {
}
}
private class QuitHandler implements Listener {
public void handleEvent(Event e) {
}
}
}
I can compile it without any errors but if I start the program then I will get the following exception:
Exception in thread "main" java.lang.NoSuchMethodError: actionProc
at org.eclipse.swt.internal.Callback.bind(Native Method)
at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
at CocoaUIEnhancer.initialize(CocoaUIEnhancer.java:124)
at CocoaUIEnhancer.hookApplicationMenu(CocoaUIEnhancer.java:92)
at Test.initUI(Test.java:50)
at Test.<init>(Test.java:18)
It's probably an error in the native libraries but I can't figure it out!
I didn't use CocoaUIEnhancer at all, as it was causing issues as well.
So here's what I ended up doing in my applications:
/**
* Convenience method that takes care of special menu items (About, Preferences, Quit)
*
* #param name The name of the menu item
* #param parent The parent {#link Menu}
* #param listener The {#link Listener} to add to the item
* #param id The <code>SWT.ID_*</code> id
*/
private void addMenuItem(String name, Menu parent, Listener listener, int id)
{
if (OSUtils.isMac())
{
Menu systemMenu = Display.getDefault().getSystemMenu();
for (MenuItem systemItem : systemMenu.getItems())
{
if (systemItem.getID() == id)
{
systemItem.addListener(SWT.Selection, listener);
return;
}
}
}
/* We get here if we're not running on a Mac, or if we're running on a Mac, but the menu item with the given id hasn't been found */
MenuItem item = new MenuItem(parent, SWT.NONE);
item.setText(name);
item.addListener(SWT.Selection, listener);
}
Just call it with SWT.ID_PREFERENCES, SWT.ID_ABOUT and SWT.ID_QUIT respectively. Hand in a fallback menu item name, a fallback Menu and the actual Listener you want to add to the menu item.
So for example:
addMenuItem("Quit", myMenu, new Listener()
{
#Override
public void handleEvent(Event event)
{
// Close database connection for example
}
}, SWT.ID_QUIT);
It looks like this the actionProc
int actionProc( int id, int sel, int arg0 )
in CocoaUIEnhancer probably needs to use long rather than int for the arguments to work with 64 bit SWT.
You need to modify CocoaUIEnhancer.java, to make it work with pure SWT application as described in this tutorial:
Modify the getProductName() method to return a String when no product is found (instead of null)
Wrap the code in hookWorkbenchListener() in a try-catch (IllegalStateException e) block
Wrap the code in modifyShells() in a try-catch (IllegalStateException e) block
Add some code to the actionProc(...) method, to bring up an About-Dialog and Preferences-Dialog (since we aren’t using commands):
static long actionProc(long id, long sel, long arg0) throws Exception {
// ...
else if (sel == sel_preferencesMenuItemSelected_) {
showPreferences();
} else if (sel == sel_aboutMenuItemSelected_) {
showAbout();
}
return 0;
}
private static void showAbout() {
MessageDialog.openInformation(null, "About...",
"Replace with a proper about text / dialog");
}
private static void showPreferences() {
System.out.println("Preferences...");
PreferenceManager manager = new PreferenceManager();
PreferenceDialog dialog = new PreferenceDialog(null, manager);
dialog.open();
}
// ...
Finally, we add the following lines to our main() method:
public static final String APP_NAME = "MyApp";
public static void main(String[] args) {
//in your case change the Test constructor
Display.setAppName(APP_NAME);
Display display = Display.getDefault();
//insert in initUI method call the earlysetup
if (SWT.getPlatform().equals("cocoa")) {
new CocoaUIEnhancer().earlyStartup();
}
Shell shell = new Shell(display);
shell.setText(APP_NAME);
...
}
Quoted code.
Baz's solution works great! If you'd rather not import OSUtils just to test if you are on a Mac, use instead:
System.getProperty("os.name").contentEquals("Mac OS X")
Currently I am developing a program which transfers a list item into another list. It works well with setOnDragExited,if I drag it to another component with the setOnDragExited, it will be dropped. (Which I think the program is rightbecause that is the function of setOnDragExited. But I need the program to only drop the list item when I release the button).
So I have the source which is fieldList and the target which is mainTable
Here is the code for the source, which I have no problem with.
fieldList.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
/* drag was detected, start a drag-and-drop gesture*/
/* allow any transfer mode */
Dragboard db =fieldList.startDragAndDrop(TransferMode.ANY);
/* Put a string on a dragboard */
ClipboardContent content = new ClipboardContent();
content.putString(fieldList.getSelectionModel().getSelectedItem());
db.setContent(content);
event.consume();
}
});
And here is the code which doesn't work with setOnDragDropped but works with setOnDragExited
mainTable.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
System.out.println("onDragDropped");
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
ObservableList<String> ls = FXCollections.observableArrayList();
try {
columnLS.add(Resources.getgBCon().getActualName(tableList.getSelectionModel().getSelectedItem())+"."+db.getString());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
success = true;
String base= "";
if(!columnLS.isEmpty()){
for(int i = 0; i<= columnLS.size()-1 ;i++){
if(i == 0){
base = columnLS.get(i);
}else{
base = base + ", " + columnLS.get(i);
}
}
}
columnQuery = base;
me.refreshSQLQuery(columnQuery,getTableQuery(),filterQuery,groupQuery,sortQuery);
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(true);
event.consume();
}
});
So far I didn't find anything that relates to my problem, on those that are remotely related I found, I have tried but to no avail.
Thank you Stack Overflow.
I have added setOnDragEntered. It seems it still didn't work. Is there a difference between setOnDrag and setOnMouseDrag?
mainTable.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
System.out.println("onDragEntered");
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
});
I have also tried TransferMode.ANY but to no avail.
Solution:
Used mainTable.setOnDragOver instead of mainTable.setOnDragEntered
I have a customized JFileChooser
Its approveSelection() method is slightly modified:
public void approveSelection()
{
File file = getSelectedFile();
changeGui();
final Object a = makeALongCalcualtion(file);
if (a != null)
{
super.approveSelection();
SwingWorker<Document, Void> open = new SwingWorker<Document, Void>()
{
#Override
protected Document doInBackground() throws Exception
{
return createADocument(a);
}
#Override
protected void done()
{
try
{
if(get() != null)
{
changeGui();
}
else
{
//TODO error message
changeGui();
}
}
catch (InterruptedException | ExecutionException e)
{
//TODO error message
changeGui();
}
}
};
open.execute();
}
else
{
//TODO error message
changeGui();
}
}
The changeGui() method sets a JProgressBar to indeterminate and updates a JLabel with a new string.
If file provided to makeALongCalcualtion(file) is of invalid type, it will return null, otherwise it returns info that is passed to SwingWorker which can use it to acutally create the representation of a file in the program (the Document object).
However, this doesn't work as it should because makeALongCalcualtion(file) isn't called within SwingWorker method, and that blocks the EDT.
In order to fix the problem, I would have to call makeALongCalcualtion(file) within a SwingWorker. I could move that part of the code into the SwingWorker without any problems, but then I would have to (due to my code logic) move super.approveSelection() along with it.
So the bottom line is, how do I call super.approveSelection() from within doInBackground() for this specific case?
//More info
What is supposed to happen:
User selects and opens a file
JLabel and JProgressBar are updated, indeterminate progress starts to play.
If makeALongCalcualtion(file) return null user is warned with an error window, but the JFileChooser stys open, making it possible to choose again when the error window is closed.
Otherwise, super.approveSelection() is called, allowing the chooser to close.
A document is created (but the method that creates the document return null if something goes wrong).
If everything is fine, JLabel updates and progressBar animation is stopped (indeterminate is set to false).
If something goes wrong same thing happens as in step 6, only with different message in JLabel.
What happens:
same
same
same, but when makeALongCalculation(file); begins, progressBar freezes.
same
same
same, but the animation isn't stopped (since the progressbar is frozen), only the frozen "picture" is removed and progressbar returns to it's previous state.
same
EDIT
I have made some alterations to my program and I now have this:
approveSelection():
public void approveSelection()
{
File file = getSelectedFile();
Main.getStatusBar().startOpen();
final WorkOpen open = new WorkOpen(file);
open.execute();
open.addPropertyChangeListener(new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
if (evt.getNewValue().equals("DONE"))
{
if (open.failed())
{
//TODO error message
Main.getStatusBar().endOpen(false);
}
else
{
Main.getStatusBar().endOpen(true);
}
}
}
}
});
}
SwingWorker:
class WorkOpen extends SwingWorker<Document, Void>
{
boolean failed = false;
File file;
public boolean failed()
{
return failed;
}
#Override
protected Document doInBackground() throws Exception
{
ArrayList<String> data = Opener.extractData(file);
if (data != null)
{
//My little path/name/similar managing system
FileComplex fullPath = new FileComplex(file.toString());
return Opener.createDocument(fullPath.getFullName(), fullPath.getFullPath(), data);
}
else
{
failed = true;
return null;
}
}
#Override
protected void done()
{
try
{
if(get() != null)
{
Main.addDocument(get());
}
}
catch (InterruptedException | ExecutionException e)
{
failed = true;
}
}
WorkOpen(File file)
{
this.file = file;
}
}
The problem now is where to call super.approveSelection(). It has to wait for the worker to finish executing, yet I can't call it from the property change listener.
What to do here?
EDIT 2
As HovercraftFullOfEels suggested, I fixed my code and it compiled and ran. But the problem of JProgressBar freezeing remained. Also, I had to introduce something I don't know if I should have:
private void superApproveSelection()
{
super.approveSelection();
}
public void approveSelection()
{
final File file = getSelectedFile();
class OpenWorker extends SwingWorker<Boolean, Void>
{
Document document;
Document getDocument()
{
return document;
}
#Override
protected Boolean doInBackground() throws Exception
{
ArrayList<String> data = Opener.extractData(file);
if (data != null)
{
//I had to start the progressBar here, because if invalid
//file was selected (extractData(file) returns null if it was),
//nothing should happen (maybe an error
//window later, handled with a new Runnable() same as this:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
Main.getStatusBar().startOpen();
}
});
FileComplex fullPath = new FileComplex(file.toString());
document = Opener.createDocument(fullPath.getFullName(), fullPath.getFullPath(), data);
return true;
}
else
{
return false;
}
}
};
final OpenWorker opener = new OpenWorker();
opener.addPropertyChangeListener(new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent evt)
{
if ("state".equals(evt.getPropertyName()))
{
if (evt.getNewValue() == SwingWorker.StateValue.DONE)
{
if(opener.getDocument() != null)
{
superApproveSelection();
Main.addDocument(opener.getDocument());
Main.getStatusBar().endOpen(true);
}
else
{
try
{
//I'm retrieveing doInBackground()'s value to see if
//progressBar needs stoping (it also displays some
//text, so it must not be called unless the
//progressBar was started).
if (opener.get())
{
Main.getStatusBar().endOpen(false);
}
}
catch (InterruptedException | ExecutionException e)
{
//TODO error something went wrong
}
}
}
}
}
});
opener.execute();
}
"In order to fix the problem, I would have to call makeALongCalcualtion(file) within a SwingWorker. I could move that part of the code into the SwingWorker without any problems, but then I would have to (due to my code logic) move super.approveSelection() along with it."
No, not true at all. super.approveSelection() would not have to be called inside of the SwingWorker.
Why not simply create a SwingWorker, add a PropertyChangeListener to it, and when the SwingWorker's state is done, call super.approveSelection() if indicated?
OK, here is my example below. Explanation to follow:
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
import javax.swing.text.*;
#SuppressWarnings("serial")
public class ApproveSelectionTest extends JPanel {
private JTextArea textArea = new JTextArea(30, 60);
public ApproveSelectionTest() {
textArea.setEditable(false);
textArea.setFocusable(false);
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new MyGetFileAction("Get Text File Text")));
setLayout(new BorderLayout());
add(new JScrollPane(textArea), BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private class MyGetFileAction extends AbstractAction {
public MyGetFileAction(String text) {
super(text);
}
public void actionPerformed(java.awt.event.ActionEvent arg0) {
MyFileChooser myFileChooser = new MyFileChooser();
int result = myFileChooser.showOpenDialog(ApproveSelectionTest.this);
if (result == JFileChooser.APPROVE_OPTION) {
Document doc = myFileChooser.getDocument();
textArea.setDocument(doc);
}
};
}
private static void createAndShowGui() {
ApproveSelectionTest mainPanel = new ApproveSelectionTest();
JFrame frame = new JFrame("ApproveSelectionTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyFileChooser extends JFileChooser {
private WorkOpen workOpen = null;
private JDialog progressDialog = null;
public MyFileChooser() {
}
#Override
public void approveSelection() {
JProgressBar progBar = new JProgressBar();
progBar.setIndeterminate(true);
Window win = SwingUtilities.getWindowAncestor(this);
progressDialog = new JDialog(win, "Checking File", ModalityType.APPLICATION_MODAL);
progressDialog.getContentPane().add(progBar);
progressDialog.pack();
progressDialog.setLocationRelativeTo(null);
File file = getSelectedFile();
workOpen = new WorkOpen(file);
workOpen.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (SwingWorker.StateValue.DONE == pcEvt.getNewValue()) {
if (progressDialog != null) {
progressDialog.dispose();
}
try {
boolean bool = workOpen.get().booleanValue();
if (bool) {
superApproveSelection();
} else {
JOptionPane.showMessageDialog(MyFileChooser.this, "Invalid File Chosen");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
workOpen.execute();
progressDialog.setVisible(true);
}
// ****** this is key *****
private void superApproveSelection() {
super.approveSelection();
}
public Document getDocument() {
if (workOpen == null) {
return null;
} else {
return workOpen.getDocument();
}
}
}
class WorkOpen extends SwingWorker<Boolean, Void> {
private static final long SLEEP_TIME = 4 * 1000;
private Document document = null;
private File file = null;
public WorkOpen(File file) {
this.file = file;
}
#Override
protected Boolean doInBackground() throws Exception {
if (file == null || !file.exists()) {
return Boolean.FALSE;
}
Thread.sleep(SLEEP_TIME);
String fileName = file.getName();
if (fileName.contains(".txt")) {
Scanner scan = new Scanner(file);
StringBuilder stringBuilder = new StringBuilder();
while (scan.hasNextLine()) {
stringBuilder.append(scan.nextLine() + "\n");
}
document = new PlainDocument();
document.insertString(0, stringBuilder.toString(), null);
return Boolean.TRUE;
}
return Boolean.FALSE;
}
public Document getDocument() {
return document;
}
}
Explanation and key points from my example:
This example behaves very simply. You choose a file, and if the file exists and contains ".txt" in its name, then it reads in the document and displays the text in a JTextField.
Else it displays a warning message but leaves the JFileChooser displayed.
Probably the key point: I've given my MyFileChooser class a private superApproveSelection() method that can be called by my PropertyChangeListener. This exposes the super's approveSelection() method to the inner class, one of the problems you were having.
The order of calling code is important in my approveSelection() override.
In this method I first create my JProgressBar and its dialog but don't yet display it immediately. It really doesn't have to be created first, but it sure needs to be displayed last.
I create my SwingWorker, workOpen, but don't yet execute it.
I add my PropertyChangeListener to the SwingWorker before executing the SwingWorker.
I then execute my SwingWorker
I then display my modal JDialog with the indeterminate JProgressBar.
My SwingWorker is structured so that its doInBackground returns a Boolean, not a Document.
I have it create a (very simple) Document if all works out OK that holds the content of the text file, and set a private "doc" field obtainable by a getter method, and then have doInBackground return Boolean.TRUE if all works well.
I've given my doInBackground a Thread.sleep(4000) just to pretend that its action takes a lot of time. Yours of course won't have this.
In the PropertyChangeListener if the SwingWorker is DONE, I'll dispose of the progress bar dialog and then call get() on the SW to get the Boolean result.
If it's Boolean.TRUE, then call the superApproveSelection() method described above.
Else show an error message. Note that since the super's approveSelection() isn't called, the file chooser dialog remains displayed.
If the approveSelection is called then the code that displays my file chooser dialog will get the appropriate return value, will extract the Document from the file chooser and displays the Document in a JTextArea.
I have developed a two plugins, plugin1 and plugin2. In plugin1 there is a one view called pluginOneView and in plugin2 there is another view called pluginTwoView. So my requirement is there will be few dragabble components on pluginTwoView and I should be able to drag it to pluginOneView. Currently I am developing drag and drop for the same, my code is (in pluginView2) for DragSource :
DragSource ds = new DragSource(btn, DND.DROP_MOVE); //btn is a draggable component
ds.setTransfer(new Transfer[] { TextTransfer.getInstance() });
ds.addDragListener(new DragSourceAdapter() {
// There are dragStart and other methods here
}
}
But my problem lies in DropTarget method:
DropTarget target = new DropTarget(component, dtl);
Here in the place of component I need to add target as pluginOneView (which is in another view). My question is how can I get a component object of that view in the workspace, so that I can pass it as a arugment to DropTarget method?
I tried of getting
PlatformUI.getWorkbench().getViewRegistry().find("targetId");
But it returns me of IViewDescriptor type, where as I need of component type. Can anyone help me in this? Since I am new to Eclipse plugin development.
Well I think you misunderstood how to use a DropTarget. You don't need to know the Plugin you're dragging to. You also used a TextTransfer, but I assume you want to drag Java Objects not Strings. Therefore I made this little example that shows how to drag objects between multiple views (which could be in different plugins). In my example an Object of type ISomeClass is transferred. In order to transfer it, ISomeClass must be serializable. I have provided my own TransferType the SomeClassTransfer class that handles the transfer. Be aware that both view plugins need access to the ISomeClass and SomeClassTransfer definitions. The easiest way to accomplish this is to make a third plugin which holds these classes. Both view plugins could then hold a reference to this third plugin.
SomeClassTransfer:
public class SomeClassTransfer extends ByteArrayTransfer {
private final static String[] typeNames;
private final static int[] typeIds;
private final static SomeClassTransfer instance;
static {
String typeName = "SomeClassTransfer";
int id = registerType(typeName);
typeNames = new String[] { typeName };
typeIds = new int[] { id };
instance = new SomeClassTransfer();
}
public static SomeClassTransfer getInstance() {
return instance;
}
private SomeClassTransfer() {
}
#Override
protected int[] getTypeIds() {
return typeIds;
}
#Override
protected String[] getTypeNames() {
return typeNames;
}
#Override
protected void javaToNative(Object object, TransferData transferData) {
if (object instanceof ISomeClass) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(object);
byte[] objectBytes = bos.toByteArray();
object = objectBytes;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
super.javaToNative(object, transferData);
}
#Override
protected ISomeClass nativeToJava(TransferData transferData) {
ISomeClass someClass = null;
byte[] objectBytes = (byte[]) super.nativeToJava(transferData);
ByteArrayInputStream bis = new ByteArrayInputStream(objectBytes);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
Object o = in.readObject();
if (o instanceof ISomeClass) {
someClass = (ISomeClass) o;
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
bis.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return someClass;
}
}
The source view:
int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
Transfer[] types = new Transfer[] { SomeClassTransfer.getInstance() };
DragSource source = new DragSource(tableViewer.getControl(), operations);
source.setTransfer(types);
source.addDragListener(new DragSourceListener() {
#Override
public void dragStart(DragSourceEvent event) {
if (tableViewer.getSelection().isEmpty()) {
// do not start drag
event.doit = false;
}
}
#Override
public void dragSetData(DragSourceEvent event) {
if (SomeClassTransfer.getInstance().isSupportedType(
event.dataType)) {
event.data = ((IStructuredSelection) tableViewer
.getSelection()).getFirstElement();
}
}
#Override
public void dragFinished(DragSourceEvent event) {
// A Move operation has been performed so remove the data
// from the source
if (event.detail == DND.DROP_MOVE) {
tableViewer.remove(((IStructuredSelection) tableViewer
.getSelection()).getFirstElement());
}
}
});
The destination view:
int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
Transfer[] types = new Transfer[] { SomeClassTransfer.getInstance() };
DropTarget target = new DropTarget(tableViewer.getControl(), operations);
target.setTransfer(types);
target.addDropListener(new DropTargetListener() {
#Override
public void dragEnter(DropTargetEvent event) {
}
#Override
public void dragOver(DropTargetEvent event) {
}
#Override
public void dragLeave(DropTargetEvent event) {
}
#Override
public void dragOperationChanged(DropTargetEvent event) {
}
#Override
public void dropAccept(DropTargetEvent event) {
}
#Override
public void drop(DropTargetEvent event) {
if (event.data == null) {
// no data to copy, indicate failure in event.detail
event.detail = DND.DROP_NONE;
return;
}
// data copied to viewer
tableViewer.add((ISomeClass) event.data);
}
});
This code enables you to drag data between two completely independent views.
I have JTabbedPane with 4 tabs. JtabbedPane is situated on a JLayeredPane. 1st and 4th tab contain JTable with custom models. Each of the tables is being refreshed every 5-10 seconds.
When 1st tab is active, and JTable on 4th has just finished refreshing, I can see content of the 4th on the 1st. Look at the screenshot.
When I click on the other tab, or minimize window, that strange effect is gone. Till the next refresh of that table on 4th tab. Refreshing is done using Future<> object.
I used Swing GUI builder in Netbeans, so I have huge amount of code. Would post any piece which could be useful.
I tried to revalidate jTabbedPane, is had no effect. Both tables and jScrollPanes has opaque property set to true. So I tried to use SwingUtilities.invokeLater(). It helped a little bit - now first content update goes well, but later - the same problem.
2nd table model has method to update it's content
public void setData(LinkedList<Object[]> __rows) {
NewDevsTableModel.__rows = __rows;
fireTableDataChanged();
}
It is used here (I added SwingUtilities here)
static class checkNew implements Callable<Boolean> {
#Override
public Boolean call() {
ServiceMessage sm = ServiceMessage.getNewList();
try {
connect();
os.write(sm.serialize());
for (int i=0; i<10; i++) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {}
if (is.available() > 0) {
break;
}
if (i == 9) {
disconnect();
return false;
}
}
byte[] actByte = new byte[is.available()];
is.read(actByte);
try {
sm = ServiceMessage.Deserialize(actByte); //may be there are no new devices
if (sm.getType() == ServiceMessageType.NODATA) {
MainWindow.jTabbedPane1.setEnabledAt(3, false);
if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
MainWindow.jTabbedPane1.setSelectedIndex(0);
}
return true;
} else {
return false; //wrong answer type
}
} catch (ClassCastException | StreamCorruptedException e) {
//remember selection and scroll
final int scroll = MainWindow.jScrollPane3.getVerticalScrollBar().getValue();
final int[] rows = MainWindow.newDevsTable.getSelectedRows();
int col = MainWindow.devicesTable.getSelectedColumn();
String[] parts = new String(actByte).split("\n");
final LinkedList<Object[]> l = new LinkedList();
for (int i=0; i<parts.length; i++) {
String[] dev = parts[i].split(";", -1);
String descr = dev[2];
boolean iptype = (!dev[3].equals("-"));
String address = dev[4];
boolean atmtype = (dev[5].equals("+"));
if (MainWindow.newDevsTable.getRowCount() >= (i+1)) {
if ((MainWindow.newDevsTable.getValueAt(i, 4) != null) && !MainWindow.newDevsTable.getValueAt(i, 4).equals("")) {
descr = MainWindow.newDevsTable.getValueAt(i, 4).toString();
}
}
Object[] o = {dev[0], dev[1], MainWindow.language[180], MainWindow.language[4], descr, iptype, address, atmtype};
l.add(o);
}
if (!l.isEmpty()) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
MainWindow.newDevsPanel.setVisible(true);
MainWindow.jTabbedPane1.setEnabledAt(3, true);
((NewDevsTableModel)MainWindow.newDevsTable.getModel()).setData(l);
ButtonColumn buttonColumn = new ButtonColumn(MainWindow.newDevsTable, addAction, 2, true);
buttonColumn = new ButtonColumn(MainWindow.newDevsTable, rejAction, 3, false);
//put selection back
for (int i=0; i<rows.length; i++) {
MainWindow.newDevsTable.addRowSelectionInterval(rows[i], rows[i]);
}
MainWindow.jScrollPane3.getVerticalScrollBar().setValue(scroll);
}
});
} else {
MainWindow.jTabbedPane1.setEnabledAt(3, false);
if (MainWindow.jTabbedPane1.getSelectedIndex() == 3) {
MainWindow.jTabbedPane1.setSelectedIndex(0);
}
}
return true;
}
} catch (IOException e) {
disconnect();
return false;
} catch (ClassNotFoundException e) {
return false;
}
}
}
I submit the task this way
public static Future<Boolean> checkNewDevices() {
final Future<Boolean> task;
task = service.submit(new checkNew());
return task;
}
To refresh automatically I use separate thread
public class CheckNewPassThread extends Thread {
int pause = 10000;
#Override
public void run() {
for (;;) {
HostConnection.checkNewDevices();
try {
Thread.sleep(pause);
} catch (InterruptedException e) {}
}
}
}
Which is started when the window is opened
private void formWindowOpened(java.awt.event.WindowEvent evt) {
HostConnection.getData();
HostConnection.getDeviceAddress();
RefreshData refreshThread = new RefreshData();
refreshThread.start();
new CheckNewPassThread().start();
}
OMG, the problem was in calling jTabbedPane.setEnabledAt(3, true) to already enabled tab. Swing is fascinating