I'm trying to change the taskbar's and the program's icon, but when I use the code I have the icon is just the default program icon. Here is my code:
public ByteBuffer loadIcon(String filename) throws IOException {
BufferedImage image = ImageIO.read(getClass().getResource(filename));
byte[] imageBytes = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
return ByteBuffer.wrap(imageBytes);
}
and in my initialisation, I call:
Display.setIcon(new ByteBuffer[] {
loadIcon("/icon16.png"),
loadIcon("/icon32.png")
});
What is wrong here?
EDIT
Have also tried this.
public void setIcons(String[] refs) throws SlickException {
ByteBuffer[] bufs = new ByteBuffer[refs.length];
for (int i=0;i<refs.length;i++) {
LoadableImageData data;
boolean flip = true;
if (refs[i].endsWith(".tga")) {
data = new TGAImageData();
} else {
flip = false;
data = new ImageIOImageData();
}
try {
bufs[i] = data.loadImage(getClass().getResourceAsStream(refs[i]), flip, false, null);
} catch (Exception e) {
Log.error(e);
throw new SlickException("Failed to set the icon");
}
}
Display.setIcon(bufs);
}
setIcons(new String[] {
"/icon16.png",
"/icon24.png",
"/icon32.png"
});
Have also tried without icon24.png. Neither works.
Related
I am trying to achieve a slideshow, gif etc. I have listed images read from a folder and make them a sequence for displaying in a SWT dialog. now I have a trouble with thread access. What is the way of making slideshow in SWT. thanks for any advice and correction.
here is the implementation:
public class ImageShowDialog extends Dialog {
Shell dialog;
private Label labelImage;
private Canvas canvas;
int numberImage = 0;
private volatile boolean running = true;
ImageShowDialog(Shell parent) {
super(parent);
}
public String open() {
Shell parent = getParent();
dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialog.setSize(600, 400);
dialog.setText("Show Begins!!!");
dialog.setLayout(new FillLayout());
this.func();
dialog.open();
Display display = parent.getDisplay();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return "After Dialog";
}
public void func() {
final List<byte[]> imageCollection = new ArrayList<byte[]>();
File path = new File("..\\folder");
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) { // this line weeds out other
// directories/folders
try {
imageCollection.add(loadImage(files[i]));
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
new Thread(new Runnable() {
#Override
public void run() {
while (running) {
ImageData imageData = new ImageData(
new ByteArrayInputStream(
imageCollection.get(numberImage)));
final Image image = new Image(Display.getDefault(),
imageData);
canvas = new Canvas(dialog, SWT.NONE);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setAlpha(255);
e.gc.drawImage(image, 0, 0);
}
});
numberImage++;
if (numberImage == imageCollection.size())
try {
running = false;
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public byte[] loadImage(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", bos);
return bos.toByteArray();
}
and exception:
Exception in thread "Thread-45" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4282)
at org.eclipse.swt.SWT.error(SWT.java:4197)
at org.eclipse.swt.SWT.error(SWT.java:4168)
at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:359)
at org.eclipse.swt.widgets.Widget.checkParent(Widget.java:279)
at org.eclipse.swt.widgets.Widget.<init>(Widget.java:149)
at org.eclipse.swt.widgets.Control.<init>(Control.java:110)
at org.eclipse.swt.widgets.Scrollable.<init>(Scrollable.java:75)
at org.eclipse.swt.widgets.Composite.<init>(Composite.java:95)
at org.eclipse.swt.widgets.Canvas.<init>(Canvas.java:79)
You can only create and access SWT controls in the main UI thread, any attempt to do so in other threads will give the 'invalid thread access' error you are getting.
You can use the asyncExec or syncExec method of Display in your background thread to run code in the main thread:
Display.getDefault().asyncExec(() ->
{
... code accessing the UI
});
(Java 8/9 code using a lambda, use a Runnable for old Java).
asyncExec runs the code asynchronously, syncExec waits for the UI thread to run the code before returning.
SWT is singlethreaded, as described by Riduidel in this post: Updating SWT objects from another thread
So, instead of doing what you do, try the below:
Display.getDefault().asyncExec(new Runnable() {
public void run() {
ImageData imageData = new ImageData(
new ByteArrayInputStream(
imageCollection.get(numberImage)));
final Image image = new Image(Display.getDefault(),
imageData);
canvas = new Canvas(dialog, SWT.NONE);
...
}
});
Very simply, I could not draw this image.
public class RenderMap extends JPanel {
static BufferedImage brick;
static BufferedImage groundb;
public static void main(String[] args) {
JFrame window = new JFrame("Super Mario");
RenderMap content = new RenderMap();
window.setContentPane(content);
window.setBackground(Color.WHITE);
window.setSize(1200, 800);
window.setLocation(100,0);
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setResizable(false);
window.setVisible(true);
try {
brick = ImageIO.read(new File("SuperMario/brick.png"));
} catch (IOException e) {
}
try {
URL url = new URL("SuperMario/brick.png");
brick = ImageIO.read(url);
} catch (IOException e) {
}
try {
groundb = ImageIO.read(new File("SuperMario/ground.png"));
} catch (IOException e) {
}
try {
URL url = new URL("SuperMario/ground.png");
groundb = ImageIO.read(url);
} catch (IOException e) {
}
}
public Ground ground;
public RenderMap() {}
public void paintComponent(Graphics g) {
if(ground == null) {
ground = new Ground();
}
ground.draw(g);
}
public class Ground implements ImageObserver {
Ground(){}
void draw(Graphics g) {
g.drawImage(groundb, 0, 0, 1200, 800, this);
g.fillOval( 8, 8, 16, 16);
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
// TODO Auto-generated method stub
return false;
}
}
}
This draws the oval, but not the image. I tried changing to another image(that is functioning in another program) and it still won't work, so I know it's not the image's problem.
As suspected, the images are not being loaded properly.
java.net.MalformedURLException: no protocol: SuperMario/brick.png
at java.net.URL.<init>(URL.java:586)
at java.net.URL.<init>(URL.java:483)
at java.net.URL.<init>(URL.java:432)
at RenderMap.main(RenderMap.java:40)
java.net.MalformedURLException: no protocol: SuperMario/ground.png
at java.net.URL.<init>(URL.java:586)
at java.net.URL.<init>(URL.java:483)
at java.net.URL.<init>(URL.java:432)
at RenderMap.main(RenderMap.java:51)
It's failing at the load-by-URL function calls because you passed in an invalid URL. Correct URL format should be like how you access them from a web browser, like: http://someplace.com/SuperMarioFolder/brick.png
To load the images, choose only one way to read them. Either by:
URL - Remove the File blocks and make the file accessible via full URL.
try {
URL url = new URL("http://www.proper-url.com/SuperMario/ground.png");
groundb = ImageIO.read(url);
} catch (IOException e) { }
File - Remove the URL blocks. This will only allow the program to access local files.
try {
groundb = ImageIO.read(new File("SuperMario/ground.png"));
} catch (IOException e) {
}
For your project's purpose, I believe option#2 would suffice.
Moving forward, you may want to use an IDE's debugging feature to go through code execution step-by-step. If you're not using one, you may want to IntelliJ and Eclipse.
Here's a screenshot application. Compiled with 1.8 JDK, works perfectly well in 64 bit systems, but lags and hangs in two iterations in 32 bit systems.
Basically this application takes a screenshot using robot class, takes the file name from user which is a URL. Truncates and removes all illegal characters from it and saves it using a save as dialog box with time-stamp as the prefix.
I am using Windows Low Level KeyHook to initiate the screenshot with PrtSc key.
Error in 32 bit systems:
It only takes 2 screenshots and then does not respond when I press PrtSc for the 3rd time. Can JFrame cause any problems, it certainly loads up slow. Should I use any alternate text box than JFrame or is it because I have complied in java 1.8 jdk 64 bit environment, which wont work in lower versions of jdk or 32 bit systems.
public class KeyHook {
private static HHOOK hhk;
private static LowLevelKeyboardProc keyboardHook;
static JFileChooser fileChooser = new JFileChooser();
public static void main(String[] args) {
final User32 lib = User32.INSTANCE;
HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
keyboardHook = new LowLevelKeyboardProc() {
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
if (nCode >= 0) {
switch(wParam.intValue()) {
case WinUser.WM_KEYUP:
case WinUser.WM_KEYDOWN:
case WinUser.WM_SYSKEYUP:
case WinUser.WM_SYSKEYDOWN:
if (info.vkCode == 44) {
try {
Robot robot = new Robot();
// Capture the screen shot of the area of the screen defined by the rectangle
BufferedImage bi=robot.createScreenCapture(new Rectangle(0,25,1366,744));
JFrame frame = new JFrame();
JFrame.setDefaultLookAndFeelDecorated(true);
frame.toFront();
frame.requestFocus();
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// prompt the user to enter their name
String name = JOptionPane.showInputDialog(frame, "Enter file name");
// frame.pack();
frame.dispose();
String fileName= dovalidateFile(name);
FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG", ".png");
fileChooser.setFileFilter(filter);
fileChooser.setSelectedFile(new File (fileName));
int returnVal = fileChooser.showSaveDialog(null);
if ( returnVal == JFileChooser.APPROVE_OPTION ){
File file = fileChooser.getSelectedFile();
file = validateFile(file);
System.out.println(file);
ImageIO.write(bi, "png", file);
}
}
catch (NullPointerException e1)
{e1.printStackTrace(); }
catch (AWTException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
}
private File validateFile(File file) {
DateFormat dateFormat = new SimpleDateFormat("HH.mm.ss.ddMMMMMyyyy");
//get current date time with Calendar()
Calendar cal = Calendar.getInstance();
// System.out.println(dateFormat.format(cal.getTime()));
String filePath = file.getAbsolutePath();
if (filePath.indexOf(".png") == -1) {
filePath += "." + dateFormat.format(cal.getTime()) + ".png";
}
//System.out.println("File Path :" + filePath);
file = new File(filePath);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
private String dovalidateFile(String name) {
String input = name.replace("https://www.","");
input = input.replaceAll("http://www.","");
input = input.replaceAll("https://","");
input = input.replace("http://","");
input = input.replace("/?",".");
input = input.replace("/",".");
input = input.replace("|",".") ;
input = input.replace("%",".");
input = input.replace("<",".");
input = input.replace(">",".");
input = input.replaceAll("\\?",".");
input = input.replaceAll("\\*",".");
input = input.replace(":",".");
input = input.replace("\\",".");
input = Character.toUpperCase(input.charAt(0)) + input.substring(1);
return input;
}
};
hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
if(!SystemTray.isSupported()){
return ;
}
SystemTray systemTray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().getImage(KeyHook.class.getResource("/images/icon.png"));
//popupmenu
PopupMenu trayPopupMenu = new PopupMenu();
MenuItem close = new MenuItem("Exit");
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.err.println("unhook and exit");
lib.UnhookWindowsHookEx(hhk);
System.exit(0);
}
});
trayPopupMenu.add(close);
//setting tray icon
TrayIcon trayIcon = new TrayIcon(image, "captur", trayPopupMenu);
//adjust to default size as per system recommendation
trayIcon.setImageAutoSize(true);
try{
systemTray.add(trayIcon);
}catch(AWTException awtException){
awtException.printStackTrace();
}
int result;
MSG msg = new MSG();
while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
if (result == -1) {
System.err.println("error in get message");
break;
}
else {
System.err.println("got message");
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
}
lib.UnhookWindowsHookEx(hhk);
}
}
I don't have any experience with JNA, but there are several things that are wrong about your code - I don't think I got them all, but here are some:
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
quit=true;
}
});
The quit=true will never be reached because your program exit()s before it ever goes there.
2.
new Thread() {
public void run() {
while (!quit) {
try { Thread.sleep(10); } catch(Exception e) { }
}
System.err.println("unhook and exit");
lib.UnhookWindowsHookEx(hhk);
System.exit(0);
}
}.start();
doesn't make any sense since quit will never be true. Also spinning on a variable to detect a change will severly slow down your application (espacially with sleep-times of 10 ms). Why not do the unhook in your ActionListener?
3.
while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
Here I'm not too sure because I don't have experience with JNA and the windows event system. The method waits for messages sent to the specified window, but since you don't specify any (second parameter is null) I don't think you will ever get one.
For each callback you are creating a new JFrame but at the end of the method you are only hiding it using frame.setVisible(false);. Since it is still referenced from various Swing-classes it will never be garbage-collected. This creates a memory-leak which will slow down your application. You will have to call frame.dispose() to get rid of it.
So I created a simple JFrame and added a JTextPane to it to create a sorta console..
I have the following methods and variables in my class which is supposed to change the colour of text in the JTextPane.
private static final Object CurrentConsoleAttributes[] = new Object[4];
private static final SimpleAttributeSet ConsoleAttributes = new SimpleAttributeSet();
public Object[] getConsoleAttributes() {
CurrentConsoleAttributes[0] = StyleConstants.getForeground(ConsoleAttributes);
CurrentConsoleAttributes[1] = StyleConstants.getBackground(ConsoleAttributes);
CurrentConsoleAttributes[2] = StyleConstants.isBold(ConsoleAttributes);
CurrentConsoleAttributes[3] = StyleConstants.isItalic(ConsoleAttributes);
return CurrentConsoleAttributes;
}
public void setConsoleAttributes(Color Foreground, Color Background, boolean Bold, boolean Italics) {
synchronized(ConsoleAttributes) {
StyleConstants.setForeground(ConsoleAttributes, Foreground);
StyleConstants.setBackground(ConsoleAttributes, Background);
StyleConstants.setBold(ConsoleAttributes, Bold);
StyleConstants.setItalic(ConsoleAttributes, Italics);
}
}
private void setOutputAreaText(final String Text) {
SwingUtilities.invokeLater(new Runnable() { //I read that I need to use this when dealing with swing and JTextPane is a swing component.
#Override
public void run() {
try {
StyledDocument Document = Frame.this.OutputArea.getStyledDocument();
Document.insertString(Document.getLength(), Text, ConsoleAttributes);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
});
}
public void WriteLine(Object Value) {
try {
System.out.print("Hey");
setConsoleAttributes(java.awt.Color.red, Color.white, true, false);
System.out.print("Testing");
setConsoleAttributes(java.awt.Color.blue, Color.white, true, false);
System.out.println("Printing");
} catch (Exception Ex) {
Ex.printStackTrace();
}
}
However, when I call WriteLine, the entire line is written in blue or whatever colour was used last. Any ideas what I'm missing?
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.