I am currently trying to turn my JFrame into a JApplet.
It runs fine in eclipse as an applet but when I try to use it on my website it gives me an error.
Here is my Applet: http://tekhaxs.com/applet.java
You can view my java source there ^^ or below.
here is the error: http://tekhaxs.com/?page_id=146
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
public class applet extends JApplet
{
JButton newBut = new JButton("New");
JButton backBut = new JButton("Back");
Font font;
BufferedImage img = null;
BufferedImage background = null;
URL url = null;
String extension;
int linkNum = 0;
int total = 0;
int backNum = 0;
String appending;
ArrayList<String> az = new ArrayList<String>();
ArrayList<String> history = new ArrayList<String>();
public void init() //initialize everything.
{
this.setLayout(null);
backBut.addActionListener(new buttonListener());
this.add(backBut);
backBut.setBounds(300, 5, 80, 35);
newBut.addActionListener(new buttonListener());
this.add(newBut);
newBut.setBounds(400, 5, 80, 35);
font = new Font("arial",Font.BOLD,20);
makeArrays();
changeUrlExtension();
try {
background = ImageIO.read(new URL("http://puu.sh/3a7KY/d2ba48949c.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
class buttonListener implements ActionListener //Button Listener for next.
{
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == backBut){
backNum++;
extension = history.get(total - backNum - 1);
repaint();
}else if(e.getSource() == newBut){
backNum = 0;
changeUrlExtension();
history.add(extension);
total++;
repaint();
}
}
}
public void changeUrlExtension(){
int a1 = (int) Math.round(Math.random() * 51);
int a2 = (int) Math.round(Math.random() * 51);
int a3 = (int) Math.round(Math.random() * 51);
String aaa = (az.get(a3)+az.get(a2)+az.get(a1));
int linkNum = (int) Math.round(Math.random() * 13) + 20;
extension = linkNum+aaa;
try {
url = new URL("http://puu.sh/"+extension+".png");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public void paint(Graphics g) { //Paints Graphics for frame.
g.drawImage(background, 0, 0, null);
g.drawImage(getImage(), 5, 50, null);
g.setColor(Color.MAGENTA);
g.drawString("Current Picture: http://puu.sh/"+extension+".png", 10,40);
g.setFont(font);
g.drawString("Picture Number: "+(total - backNum), 10,20);
}
public Image getImage(){ //Returns Image from url.
try {
url = new URL("http://puu.sh/"+extension+".png");
} catch (IOException e) {
e.printStackTrace();
}
try {
img = ImageIO.read(url);
System.out.println(total+". "+url);
} catch (IOException e) {
changeUrlExtension();
getImage();
}
return img;
}
public void makeArrays(){ //Makes az Array.
az.add("A");
az.add("a");
az.add("B");
az.add("b");
az.add("C");
az.add("c");
az.add("D");
az.add("d");
az.add("E");
az.add("e");
az.add("F");
az.add("f");
az.add("G");
az.add("g");
az.add("H");
az.add("h");
az.add("I");
az.add("i");
az.add("J");
az.add("j");
az.add("K");
az.add("k");
az.add("L");
az.add("l");
az.add("M");
az.add("m");
az.add("N");
az.add("n");
az.add("O");
az.add("o");
az.add("P");
az.add("p");
az.add("Q");
az.add("q");
az.add("R");
az.add("r");
az.add("S");
az.add("s");
az.add("T");
az.add("t");
az.add("U");
az.add("u");
az.add("V");
az.add("v");
az.add("W");
az.add("w");
az.add("X");
az.add("x");
az.add("Y");
az.add("y");
az.add("Z");
az.add("z");
}
}
Here is the html code I use to call my JApplet.
<applet code="http://tekhaxs.com/applet.java" width="400" height="400">
If your browser was Java-enabled, a Puush Browser would appear here.
</applet>
Any suggestions on how to fix this error?
You need to provide the class file of your applet in the code attribute:
<applet code="applet.class" width="400" height="400">
This should work if the class file is at the same location as your html file. If the class file is at a different location, you need to specify the location through an additional codebase attribute, e.g. if the class file is located in a bin subdirectory, specify
<applet code="applet.class" codebase="bin" width="400" height="400">
See http://www.duckware.com/applets/reference.html for additional information.
Essentially,
code refers to the class of the main applet class, including any package names, and with a .class postfix, like in code="com.example.SampleApplet.class".
codebase is a URL (either relative or absolute) which refers to the location where the class file specified in code can be found. If it is the same location as the html file, codebase can be omitted.
now I am getting a different error.
Access denied ("java.net.SocketPermission""Puu.sh:80""connect,ressolve")
Your applet code does not have the necessary access rights to use sockets (which is required to access puu.sh which you do in your code). Note that applets are running on the client machine, and by default they are not allowed any access outside their sandbox.
You can adjust the privileges by creating a so-called policy file on the client machine - See http://download.java.net/jdk8/docs/technotes/guides/security/PolicyFiles.html for more information. Note that this needs to be done on the client side.
I would try to put the images on the same server where your applet resides. Then you should be able to download them without modifying the security policies.
Related
I am trying to implement Remote FrameBuffer Protocol using Java socket programming.
I have a server side program that takes screenshot of the entire screen using robot and store it in BufferedImage .Then I converted it into a byte array and sending it to the client .
Objective :
To display the entire screen of the server side machine in a Swing GUI of the client side.
Problem i am facing :
i am able to send the image in bytes from server and receive it from the server by the client (client.java) and convert it into a jpg image (output.jpg) using ImageIO and put that image in a Swing frame.
But i am able to see the first image in the Swing and whenever the image gets updated ,the image in the Swing is not updating or refreshing .
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
client.java
package remoteclient;
import java.lang.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.*;
import java.io.*;
public class client {
public static void main(String args[])throws Exception{
Socket s=new Socket("localhost",5900);
DataInputStream din=new DataInputStream(s.getInputStream());
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int width=0,height=0;
try {
width = din.readInt(); //getting width and height from server thru socket.
height = din.readInt();
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame("Client");
JLabel label = new JLabel();
f.setSize(width, height);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
boolean continueLoop = true;
while(continueLoop)
{
try {
int len = din.readInt();
byte[] imageInByte = new byte[len];
System.out.println(len);
din.readFully(imageInByte);
System.out.println(imageInByte);
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
BufferedImage bImage2 = ImageIO.read(bis);
// Image im1 = bImage2.getScaledInstance(width,height, Image.SCALE_SMOOTH);
ImageIO.write(bImage2, "jpg", new File("output.jpg") );
bImage2 = ImageIO.read(new File("output.jpg"));
label.setIcon(new ImageIcon(im1));
ImageIcon icon = new ImageIcon(bImage2);
icon.getImage().flush();
label.setIcon( icon );
f.getContentPane().add(label, BorderLayout.CENTER);
f.pack();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
Updated code with comments about demo code that should be removed from your working code:
Here's an example, using default UIManager icons, and SwingWorker, as noted in the comments to the original posting. You would instead use images from your server connection.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
public class SwingLabelWithUpdatedImage {
public static void main(String args[]) throws Exception {
final JLabel label = new JLabel("", SwingConstants.CENTER);
final JFrame frame = new JFrame("Client");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(label, BorderLayout.CENTER);
final Dimension preferredSize = new Dimension(200, 100);
frame.setPreferredSize(preferredSize);
frame.setVisible(true);
frame.pack();
final ImageUpdateWorker task = new ImageUpdateWorker(label);
task.execute();
}
public static class ImageUpdateWorker extends SwingWorker<Void, IconInfo> {
// iconInfoList is not need in your code. It's here so I can
// supply a dummy set of icons to demonstrate UI updates.
final List<IconInfo> iconInfoList;
private JLabel label;
ImageUpdateWorker(JLabel label) {
this.label = label;
// Delete this in your code
this.iconInfoList = initIconInfoList();
}
#Override
public Void doInBackground() {
boolean isTrue = true;
while (isTrue) {
// Put your socket code to read the next icon from a server.
// You don't need to do the ImageIO.write(), ImageIO.read() dance,
// unless you must save the icon to disk. In that case, you don't need
// to read it back in.
// Here, I just rotate the iconInfoList to make it
// appear as though a new icon was received.
// Your code will not have any need to do this.
Collections.rotate(iconInfoList, -1);
// Just publish the icon you create from the image
// you receive from your remote server.
publish(iconInfoList.get(0));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void process(List<IconInfo> icons) {
// You might check for an empty list.
// #kleopatra's suggestion to get the last icon is correct.
// See https://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html
IconInfo iconInfo = icons.get(icons.size() - 1);
label.setIcon(iconInfo.icon);
// Your code will not do this
label.setText(iconInfo.name);
// You can get the icon dimensions just from the icon,
// so you don't really need the IconInfo class.
label.setSize(iconInfo.dimension);
}
/** Demo code only. It doesn't belong in your working code.
*/
protected List<IconInfo> initIconInfoList() {
// Just a quick way to get some icons; don't need to
// fetch from a server just to demonstrate how to
// refresh the UI.
List<IconInfo> iconInfoList = UIManager.getDefaults().keySet().stream()
.filter(this::isIconKey)
.map(IconInfo::new)
.filter(iconInfo -> iconInfo.icon != null)
.collect(Collectors.toList());
return iconInfoList;
}
/** Demo code only. It doesn't belong in your working code.
*/
protected boolean isIconKey(Object key) {
return String.class.isAssignableFrom(key.getClass())
&& ((String) key).toLowerCase().contains("icon");
}
}
/** This is just a convenience to convey
* the icon and its UIManager key (i.e., name).
* Your remote server doesn't supply a name,
* so you don't really need this class.
* It's just to make the demo more expressive.
*/
public static class IconInfo {
final private String name;
final private Icon icon;
final private Dimension dimension;
IconInfo(Object name) {
this.name = name.toString();
icon = UIManager.getIcon(name);
dimension = icon == null
? new Dimension(32, 32)
: new Dimension(icon.getIconWidth(), icon.getIconHeight());
}
}
}
I've recently been experimenting with the user of JTextPanes for an upcoming project I'll be working on, there have been various posts online detailing how to go about counting the number of lines within the text pane however the solutions I found all seem to fail when inserting Icons or Components into the text pane's document.
The solution I found that worked for plain text was this one (with the solution implemented of course): BadLocationException when using Utilities.getRowStart On hit of Enter key
However once I try to insert a Component (JLabel) or a plain Icon for that matter, the getRowStart() method from Utilities throws a null pointer exception. What I find unusual about this is the Java Doc states that "...This is represented in the associated document as an attribute of one character of content. ", so I assumed it would treat it as any other character but it seems this is not the case.
I've included a code example to replicate the problem if anyone would like to try it. I have a feeling that it just simply isn't possible, which would be a shame.
import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class Test{
private JFrame frame;
private JTextPane textPane;
private Image img;
private URL imgURL;
public Test(){
frame = new JFrame();
frame.setSize(new Dimension(500,300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textPane = new JTextPane();
try {
imgURL = new URL("http://www.freeiconspng.com/uploads/floppy-save-icon--23.png");
img = ImageIO.read(imgURL);
JLabel label = new JLabel(new ImageIcon(img.getScaledInstance(10, 10, Image.SCALE_SMOOTH)));
textPane.insertComponent(label);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frame.getContentPane().add(textPane);
frame.setVisible(true);
}
public JTextPane getTextPane(){
return this.textPane;
}
public int getLineCount(){
int totalCharacters = textPane.getDocument().getLength();
int lineCount = (totalCharacters == 0) ? 1 : 0;
try {
int offset = totalCharacters;
while (offset > 0) {
offset = Utilities.getRowStart(textPane, offset) - 1;
lineCount++;
}
} catch (BadLocationException e) {
e.printStackTrace();
}
return lineCount;
}
public static void main(String[] args){
Test t = new Test();
t.getLineCount();
}
}
The problem was solved after the following comment:
It doesn't throw any exception for me once I wrap the content inside
your main method inside a EventQueue.invokeLater() call. I.e.:
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Test t = new Test();
t.getLineCount();
}
});
I am currently using this code to create a JDialog;
package com.kamuara.reposync.window;
import java.awt.Dialog;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
public class SheetDialog {
private JFrame _windowFrame;
public static void main(String[] args) {
System.setProperty("apple.awt.documentModalSheet", "true");
System.setProperty("apple.awt.brushMetalLook", "true");
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new SheetDialog();
} catch (Exception e) {
e.printStackTrace();
}
}
public SheetDialog() {
_windowFrame = new JFrame();
_windowFrame.setResizable(false);
_windowFrame.setBounds(100, 100, 451, 320);
_windowFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_windowFrame.getContentPane().setLayout(null);
_windowFrame.setVisible(true);
JButton showDialogButton = new JButton("Show Dialog");
showDialogButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
showSheetDialog(_windowFrame, "Test", "This should be a sheet dialog", "Oke");
}
});
showDialogButton.setBounds(328, 263, 117, 29);
_windowFrame.getContentPane().add(showDialogButton);
}
public void showSheetDialog(JFrame owner, String title, String message, String button) {
final JDialog messageDialog = new JDialog(owner, title, Dialog.ModalityType.DOCUMENT_MODAL);
messageDialog.setBounds(30, 0, owner.getWidth() - 60, 130);
// TODO: only when os is osx
messageDialog.getRootPane().putClientProperty("apple.awt.documentModalSheet", "true");
messageDialog.setLayout(null);
int offsetX = 25;
JLabel titleLabel = new JLabel(title);
titleLabel.setFont(new Font("Lucida Grande", Font.BOLD, 13));
titleLabel.setBounds(offsetX, 10, 100, 25);
messageDialog.getContentPane().add(titleLabel);
JLabel messageLabel = new JLabel(message);
messageLabel.setVerticalTextPosition(JLabel.TOP);
messageLabel.setHorizontalTextPosition(JLabel.LEFT);
messageLabel.setFont(new Font("Lucida Grande", Font.PLAIN, 11));
messageLabel.setBounds(offsetX, 10, messageDialog.getWidth() - 10, messageDialog.getHeight() - 60);
messageDialog.getContentPane().add(messageLabel);
JButton okButton = new JButton(button);
okButton.setBounds(messageDialog.getWidth() - 105, messageDialog.getHeight() - 35, 100, 25);
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
messageDialog.dispose();
}
});
messageDialog.getContentPane().add(okButton);
messageDialog.setVisible(true);
}
}
I was previously using Java 6 to compile the application and setting the clientProperty apple.awt.documentModalSheet was working perfectly to display the dialog as a "Sheet" on OSX but now I started using Java 7 (update 25) and the dialog is no longer displayed as a Sheet. I can't seem to find any update documentation on this. Have they changed anything about this? How can I solve this? The current interface design looks tons better with a Sheet than a dialog.
Update
I found the following Bug report which seems to be the same issue as I am experiencing;
http://bugs.sun.com/view_bug.do?bug_id=8010197
Does anyone know how to resolve this? I have looked into libraries like QuaQua but I would prefer not using any library because I just want the Sheet functionality.
Update 2
I tried QuaQua, but the library currently has the exact same problem when compiling with Java 7. Any workarounds?
Update 3
Replaced code with working sample (http://pastebin.com/PJ8VGdPb)
Update 4
Found out SWT has a style for their Shell class named SWT.SHEET which still works in Java7, I don't prefer using a library like SWT, but it seems to be the only solution.
As far as I know, Apple didn't officially released their version of JDK 7. The latest version of the JDK Apple has optimized for their OS X is still JDK 6. That is also why updates for Java come thru the AppStore update tab. These updates do not come straight from Oracle.
If you downloaded JDK 7 directly from Oracle, this is a more generic, non-tweaked version.
So, I think you will just have to wait for Apple to release their OS X optimized JDK 7.
I experienced a lot of OS X features not to be working when I download from Oracle:
Trackpad gestures
Native Aqua Look'n'Feel doesn't work, even when trying to set it manually through UIManager.
Application icon not working when using JOptionPane.
JMenu's will stick into the JFrame itself instead of moving to the top of the screen.
It seems before JDK fix the bug, you have to implement the Sheet yourself.
The key points are:
Use the glass pane of the window frame to hold the Sheet dialog
Use the GridBagLayout (with NORTH anchor) to put the dialog at top|center of the pane
Animate the Sheet when show/disappeare by painting the dialog repeatedly, every time paint more/less part of the dialog
The following is the example code
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class SheetableJFrame extends JFrame implements ActionListener {
public static final int INCOMING = 1;
public static final int OUTGOING = -1;
public static final float ANIMATION_DURATION = 1000f;
public static final int ANIMATION_SLEEP = 50;
JComponent sheet;
JPanel glass;
Sheet animatingSheet;
boolean animating;
int animationDirection;
Timer animationTimer;
long animationStart;
BufferedImage offscreenImage;
public SheetableJFrame() {
super();
glass = (JPanel) getGlassPane();
glass.setLayout(new GridBagLayout());
animatingSheet = new Sheet();
animatingSheet.setBorder(new LineBorder(Color.black, 1));
}
public JComponent showJDialogAsSheet(JDialog dialog) {
sheet = (JComponent) dialog.getContentPane();
sheet.setBorder(new LineBorder(Color.black, 1));
glass.removeAll();
animationDirection = INCOMING;
startAnimation();
return sheet;
}
public void hideSheet() {
animationDirection = OUTGOING;
startAnimation();
}
private void startAnimation() {
glass.repaint();
// clear glasspane and set up animatingSheet
animatingSheet.setSource(sheet);
glass.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
glass.add(animatingSheet, gbc);
gbc.gridy = 1;
gbc.weighty = Integer.MAX_VALUE;
glass.add(Box.createGlue(), gbc);
glass.setVisible(true);
// start animation timer
animationStart = System.currentTimeMillis();
if (animationTimer == null) animationTimer = new Timer(ANIMATION_SLEEP, this);
animating = true;
animationTimer.start();
}
private void stopAnimation() {
animationTimer.stop();
animating = false;
}
// used by the Timer
public void actionPerformed(ActionEvent e) {
if (animating) {
// calculate height to show
float animationPercent = (System.currentTimeMillis() - animationStart) / ANIMATION_DURATION;
animationPercent = Math.min(1.0f, animationPercent);
int animatingHeight = 0;
if (animationDirection == INCOMING) {
animatingHeight = (int) (animationPercent * sheet.getHeight());
} else {
animatingHeight = (int) ((1.0f - animationPercent) * sheet.getHeight());
}
// clip off that much from sheet and put it into animatingSheet
animatingSheet.setAnimatingHeight(animatingHeight);
animatingSheet.repaint();
if (animationPercent >= 1.0f) {
stopAnimation();
if (animationDirection == INCOMING) {
finishShowingSheet();
} else {
glass.removeAll();
glass.setVisible(false);
glass.setLayout(new GridBagLayout());
animatingSheet = new Sheet();
}
}
}
}
private void finishShowingSheet() {
glass.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
glass.add(sheet, gbc);
gbc.gridy = 1;
gbc.weighty = Integer.MAX_VALUE;
glass.add(Box.createGlue(), gbc);
glass.revalidate();
glass.repaint();
}
class Sheet extends JPanel {
Dimension animatingSize = new Dimension(0, 1);
JComponent source;
BufferedImage offscreenImage;
public Sheet() {
super();
setOpaque(true);
}
public void setSource(JComponent source) {
this.source = source;
animatingSize.width = source.getWidth();
makeOffscreenImage(source);
}
public void setAnimatingHeight(int height) {
animatingSize.height = height;
setSize(animatingSize);
}
private void makeOffscreenImage(JComponent source) {
GraphicsConfiguration gfxConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
offscreenImage = gfxConfig.createCompatibleImage(source.getWidth(), source.getHeight());
Graphics2D offscreenGraphics = (Graphics2D) offscreenImage.getGraphics();
source.paint(offscreenGraphics);
}
public Dimension getPreferredSize() {
return animatingSize;
}
public Dimension getMinimumSize() {
return animatingSize;
}
public Dimension getMaximumSize() {
return animatingSize;
}
public void paint(Graphics g) {
// get the bottom-most n pixels of source and paint them into g, where n is height
BufferedImage fragment = offscreenImage.getSubimage(0, offscreenImage.getHeight() - animatingSize.height,
source.getWidth(), animatingSize.height);
g.drawImage(fragment, 0, 0, this);
}
}
}
The test code
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
public class SheetTest extends Object implements PropertyChangeListener {
JOptionPane optionPane;
SheetableJFrame frame;
public static void main(String[] args) {
new SheetTest();
}
public SheetTest() {
frame = new SheetableJFrame();
// build JOptionPane dialog and hold onto it
optionPane = new JOptionPane("Do you want to close?", JOptionPane.QUESTION_MESSAGE, JOptionPane.CANCEL_OPTION);
frame.setSize(640, 480);
frame.setVisible(true);
optionPane.addPropertyChangeListener(this);
JDialog dialog = optionPane.createDialog(frame, "irrelevant");
frame.showJDialogAsSheet(dialog);
}
public void propertyChange(PropertyChangeEvent pce) {
if (pce.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
System.out.println("Selected option " + pce.getNewValue());
frame.hideSheet();
}
}
}
reference
http://oreilly.com/pub/h/4852
http://book.javanb.com/swing-hacks/swinghacks-chp-6-sect-6.html
Here's a super dodgy hack I came up with which sets the flag which the JDK now appears to be forgetting to set and manually positions the window in the right place. There's still a missing shadow though, so I wonder if anyone can improve on it. ;)
This messes with internal classes and private fields, so it might break in any given new release of the JDK, but it still works on 8u5. Maybe it will give some insight into how these internal AWT classes are structured.
public static void makeSheet(Dialog dialog) {
dialog.addNotify();
ComponentPeer peer = dialog.getPeer();
// File dialogs are CFileDialog instead. Unfortunately this means this hack
// can't work for those. :(
if (peer instanceof LWWindowPeer) {
LWWindowPeer windowPeer = (LWWindowPeer) dialog.getPeer();
//XXX: Should check this before casting too.
CPlatformWindow platformWindow = (CPlatformWindow) windowPeer.getPlatformWindow();
try {
Method method = CPlatformWindow.class.getDeclaredMethod(
"setStyleBits", int.class, boolean.class);
method.setAccessible(true);
method.invoke(platformWindow, 64 /* CPlatformWindow.SHEET */, true);
Window parent = dialog.getOwner();
dialog.setLocation(dialog.getLocation().x,
parent.getLocation().y + parent.getInsets().top);
} catch (Exception e) {
Logger.getLogger(SheetHack.class.getName())
.log(Level.WARNING, "Couldn't call setStyleBits", e);
}
}
}
I encountered a problem while I am trying to display an image after I clicked a button and chose image file within the "Choose File Dialog".
Initially, I was managed to display the chosen image in JLabel, but later I created a separate ActionListener, I think it started to go wrong since then. Whatever image I choose, the JLabel won't display it.
I debugged it, and sure that the file chooser does pass the image to ImageIcon, JLabel does get the value from ImageIcon, but it doesn't display the image even after revalidate() and repaint().
Here I attached my code for your kind reference!
(I trimmed the code for a clean look, so there might be some brackets left not useful)
package com.xxx.LoyalCardManager;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
public class LoyalCardManagerMain implements ActionListener{
private JFrame frame;
private DatabaseHandler db = new DatabaseHandler();
private JLabel labelPic;
private JButton buttonPic;
private File picFile = new File("");
private BufferedImage image;
/**
* Launch the application.
* #throws SQLException
* #throws ClassNotFoundException
*/
public static void main(String[] args) throws SQLException, ClassNotFoundException {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
LoyalCardManagerMain window = new LoyalCardManagerMain();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
/**
* Create the application.
*/
public LoyalCardManagerMain() {
// Database initialisation
initDatabase();
// Draw GUI
frame = new JFrame();
frame.setBounds(100, 100, 619, 487);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
buttonPic = new JButton("Click to Choose Pic");
buttonPic.setBounds(415, 252, 166, 29);
frame.getContentPane().add(buttonPic);
buttonPic.setEnabled(false);
buttonPic.setActionCommand("ChoosePic");
buttonPic.addActionListener(this);
labelPic = new JLabel();
labelPic.setBounds(415, 30, 167, 210);
frame.getContentPane().add(labelPic);
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("ChoosePic")) {
//TODO Label now cannot display images.
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setAcceptAllFileFilterUsed(false);
chooser.setFileFilter(new FileFilter() {
public boolean accept (File f) {
String extension = Utils.getExtension(f);
if(extension != null) {
if (extension.equals(Utils.gif) ||
extension.equals(Utils.jpeg) ||
extension.equals(Utils.jpg) ||
extension.equals(Utils.png) ||
extension.equals(Utils.tif) ||
extension.equals(Utils.tiff)) {
return true;
}else{
return false;
}
}
return false;
}
public String getDescription() {
return "Image File (*.gif, *.jpeg, *.jpg, *.png, *.tif, *.tiff)";
}
});
int retVal = chooser.showOpenDialog(frame);
if (retVal == JFileChooser.APPROVE_OPTION) {
picFile = chooser.getSelectedFile();
try {
image = ImageIO.read(picFile);
} catch (IOException e) {
e.printStackTrace();
}
// Calculate the pic's ratio and do re-scale
double ratio = (double) labelPic.getWidth() / (double) labelPic.getHeight();
// Do image scale, scaledW is the new Width, and LabelPic.getHeight is the new Height.
int scaledW = (int) (image.getHeight() * ratio);
image = new BufferedImage(scaledW, labelPic.getHeight(), BufferedImage.SCALE_FAST);
ImageIcon icon = new ImageIcon(image);
labelPic.setVisible(true);
labelPic.setIcon(icon);
labelPic.revalidate();
labelPic.repaint();
}
}
}
}
I also referenced other similar questions:
image loading using a JFileChooser into a JFrame
Image won't display in JLabel
Updating an image contained in a JLabel - problems
External Site: JFIleChooser opening image to JLabel
As well as Java Tutorial Docs
How to Use Buttons, Check Boxes, and Radio Buttons
But I still can't figure it out why the JLabel not display the chosen image.
Thanks for your kind help mates!
Ok, I finally figured out what's wrong with the code:
If I intend to use BufferedImage to resize (sorry, in my question I mis-understanding the method scale with resize), I need to use drawImage method to "redraw" the image. Otherwise the image will not be shown.
I made modification here:
double ratio = (double) labelPic.getWidth() / (double) labelPic.getHeight();
// Do image scale, scaledW is the new Width, and LabelPic.getHeight is the new Height.
int scaledW = (int) (image.getHeight() * ratio);
image = new BufferedImage(scaledW, labelPic.getHeight(), BufferedImage.SCALE_FAST);// Edit here
ImageIcon icon = new ImageIcon(image);
labelPic.setVisible(true);
labelPic.setIcon(icon);
labelPic.revalidate();
labelPic.repaint();
From the "Edit Here" mark, I use the following code:
BufferedImage imageTemp = new BufferedImage(resizedW, resizedH, BufferedImage.TYPE_INT_RGB);
imageTemp.getGraphics().drawImage(image,0,0, scaledW, scaledH, null);
image = imageTemp;
And there's difference between first pass the value to imageTemp then pass to image and directly pass the value to image. If I pass the new BufferedImage directly to image, it will display a pure black colour instead of the image you choose.
Try using this to display the image:
JfileChooser getImage = new JFileChooser();
..........
ImageIcon imagePath= new ImageIcon(getImage.getPath());
JLabel imageLabel= new JLabel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imagePath.getImage(), 0, 0, width, height, null);
}
};
imageLabel.setLocation(10, 40);
imageLabel.setBorder(viewAnimalPanelBorder);
imageLabel.setSize(200, newHeight);
panel.add(imageLabel);
Let me know if you require more assistance.
Also, try displaying the picture without using the JFileChooser, maybe hard code the path for a test.
I am trying to implement some ocr using a guide from on stackoverflow. the example code for the use of the application is using java and i am trying to run it on android. Here is the code from the example;
// OCRScannerDemo.java
// Copyright (c) 2003-2009 Ronald B. Cemer
// All rights reserved.
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.roncemer.ocr.main;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.ScrollPane;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.ImageProducer;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import com.roncemer.ocr.CharacterRange;
import com.roncemer.ocr.OCRImageCanvas;
import com.roncemer.ocr.OCRScanner;
import com.roncemer.ocr.PixelImage;
import com.roncemer.ocr.TrainingImageLoader;
import com.roncemer.ocr.tracker.MediaTrackerProxy;
/**
* Demo application to demonstrate OCR document scanning and decoding.
* #author Ronald B. Cemer
*/
public class OCRScannerDemo extends Frame {
private static final long serialVersionUID = -8030499184564680363L;
private boolean debug = true;
private Image image;
private OCRImageCanvas imageCanvas;
private OCRScanner scanner;
public OCRScannerDemo() {
super("OCR from a scanned image");
setSize(1024, 768);
ScrollPane scrollPane = new ScrollPane();
imageCanvas = new OCRImageCanvas();
scrollPane.add(imageCanvas);
add(scrollPane);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
((Frame)(e.getSource())).hide();
System.exit(0);
}
});
scanner = new OCRScanner();
show();
}
/**
* Load demo training images.
* #param trainingImageDir The directory from which to load the images.
*/
public void loadTrainingImages(String trainingImageDir) {
if (debug) System.err.println("loadTrainingImages(" + trainingImageDir + ")");
if (!trainingImageDir.endsWith(File.separator)) {
trainingImageDir += File.separator;
}
try {
scanner.clearTrainingImages();
TrainingImageLoader loader = new TrainingImageLoader();
HashMap images = new HashMap();
if (debug) System.err.println("ascii.png");
loader.load(
this,
trainingImageDir + "ascii.png",
new CharacterRange('!', '~'),
images);
if (debug) System.err.println("hpljPica.jpg");
loader.load(
this,
trainingImageDir + "hpljPica.jpg",
new CharacterRange('!', '~'),
images);
if (debug) System.err.println("digits.jpg");
loader.load(
this,
trainingImageDir + "digits.jpg",
new CharacterRange('0', '9'),
images);
if (debug) System.err.println("adding images");
scanner.addTrainingImages(images);
if (debug) System.err.println("loadTrainingImages() done");
}
catch(IOException ex) {
ex.printStackTrace();
System.exit(2);
}
}
public void process(String imageFilename) {
if (debug) System.err.println("process(" + imageFilename + ")");
String imageFileUrlString = "";
try {
imageFileUrlString = new File(imageFilename).toURL().toString();
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
ImageProducer imageProducer = (ImageProducer)
(new URL(imageFileUrlString).getContent());
image = createImage(imageProducer);
}
catch(IOException e) {
e.printStackTrace();
}
if (image == null) {
System.err.println("Cannot find image file at " + imageFileUrlString);
return;
}
MediaTracker mt = new MediaTrackerProxy(this);
mt.addImage(image, 0);
try {
mt.waitForAll();
} catch(InterruptedException ex) {}
if (debug) System.err.println("image loaded");
/* int w = image.getWidth(null);
int h = image.getHeight(null);
if ( (w > 0) && (h > 0) ) {
float scaleFactor = 2048.0f/(float)Math.max(w, h);
if (scaleFactor < 1.0f) {
image = image.getScaledInstance(
(int)((float)w*scaleFactor),
(int)((float)h*scaleFactor), Image.SCALE_SMOOTH);
mt = new MediaTrackerProxy(this);
mt.addImage(image, 0);
try { mt.waitForAll(); } catch(InterruptedException ex) {}
}
}*/
imageCanvas.setSize(image.getWidth(null), image.getHeight(null));
if (debug) System.err.println("constructing new PixelImage");
PixelImage pixelImage = new PixelImage(image);
if (debug) System.err.println("converting PixelImage to grayScale");
pixelImage.toGrayScale(true);
if (debug) System.err.println("filtering");
pixelImage.filter();
if (debug) System.err.println("setting image for display");
imageCanvas.setImage(
pixelImage.rgbToImage(
pixelImage.grayScaleToRGB(pixelImage.pixels),
pixelImage.width,
pixelImage.height,
imageCanvas));
System.out.println(imageFilename + ":");
String text = scanner.scan(image, 0, 0, 0, 0, null, imageCanvas.getGraphics());
System.out.println("[" + text + "]");
}
public static void main(String[]args) {
if (args.length < 1) {
System.err.println("Please specify one or more image filenames.");
System.exit(1);
}
String trainingImageDir = System.getProperty("TRAINING_IMAGE_DIR");
if (trainingImageDir == null) {
System.err.println
("Please specify -DTRAINING_IMAGE_DIR=<dir> on " +
"the java command line.");
return;
}
OCRScannerDemo demo = new OCRScannerDemo();
demo.loadTrainingImages(trainingImageDir);
for (int i = 0; i < args.length; i++)
demo.process(args[i]);
System.out.println("done.");
}
}
In the process method an ImageProducer is used. Is there an alternative for android or had i might as well give up using this approach?
Kind regards
A bit late reply, but I guess it may help readers.
On Android, consider the android.graphics.Bitmap class as entry point for building images.
It is a straight forward simplification about creating and using images, when compared to Java AWT API. Android's Bitmap class resembles a lot the java.awt.BufferedImage, one with set/getPixel methdos and another one with set/getRGB, as well some methods to create bitmaps (images) from different sources.