//create and display a label containing icon and a string
//JLabel and ImageIcon
import java.awt.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.JLabel.*;
public class JLabelDemo extends JApplet {
public void init() {
try {
SwingUtilities.invoke(
new Runnable() {
public void run() {
makeGUI();
}
}
);
}
catch(Exception e) {
System.out.println("Cannot happen due to exception " + e);
}
}
private void makeGUI() {
//create an icon
ImageIcon ii=new ImageIcon("The Big Trip.png");
//create a label
JLabel jl=new JLabel("India",ii,JLabel.CENTER);
add(jl);//add label to content pane
}
}
/*<applet code="JLabelDemo" height=250 width=150>*/
This code is compiled using:
javac JLabelDemo.java
But running through cmd using the following is not working (is not displaying any applet)!!
appletviewer JLabelDemo.java
Use SwingUtilities.invokeAndWait(runnable obj) instead of SwingUtilities.invoke(runnable obj)
You need to call SwingUtilities.invokeAndWait instead. And you also need to close your applet tag, for it to work in appletviewer. And you need to add your content to the content pane, rather than using add, as that merely adds to the container.
JLabelDemo.java
//create and display a label containing icon and a string
//JLabel and ImageIcon
import java.awt.*;
import java.applet.*;
import javax.swing.*;
public class JLabelDemo extends JApplet {
public void init() {
try {
SwingUtilities.invokeAndWait(
new Runnable() {
public void run() {
this.makeGUI();
}
}
);
} catch (Exception e) {
System.out.println("Cannot happen due to exception "+e);
}
}
private void makeGUI(){
//create an icon
ImageIcon ii = new ImageIcon("The Big Trip.png");
//create a label
JLabel jl = new JLabel("India", ii, JLabel.CENTER);
//add label to content pane
this.getContentPane().add(jl);
}
}
HTML:
<applet code="JLabelDemo" width="150" height="250"></applet>
Related
I am trying to get my application to display a simple loading dialog so users know when a time intensive process is working and when its done. I just want it to show a simple "loading" using a gif I downloaded. I already tried using only text and it still doesn't work.
I can get the dialog to display (and disappear) when I want it to, the problem is nothing will display on the dialog (or frame) after displaying it. I have tried many different techniques and all give the same result, a blank dialog.
I finally made a separate class to display the dialog (with loading gif) and I got it to display properly (by itself), but when I run it from my main application, it shows a black dialog again. I tested putting the gif into a JOptionPane and it works, the problem with that is I can't close it at will.
Here is my custom code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import java.util.logging.*;
import org.w3c.dom.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.filechooser.FileNameExtensionFilter;
public class Loader implements Runnable {
final JFileChooser jfc = new JFileChooser();
static JFrame frame = new JFrame();
Frame parentUI = new Frame();
JDialog dialog = new JDialog();
JLabel lbl_filename = new JLabel();
JLabel lbl_path = new JLabel();
static Loader load = new Loader(null);
public static void main(String[] args) throws InterruptedException, InvocationTargetException {
load.run();
frame.setVisible(true);
}
public Loader(Frame parent) {
init();
parentUI = parent;
}
#Override
public void run() {
createDialog(parentUI);
}
public final void init() {
JButton btn = new JButton("Open");
frame.setTitle("Loader Test");
frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new FlowLayout());
btn.addActionListener(new Action1());
frame.add(btn);
frame.add(lbl_filename);
frame.add(lbl_path);
}
class Action1 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
openFile();
load.Close();
}
}
private void createDialog(final Frame parent) {
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Loader");
URL url = this.getClass().getResource("/resource/loader.gif");
Icon icon = new ImageIcon(url);
JLabel label = new JLabel(icon);
dialog.add(label);
dialog.pack();
dialog.setLocationRelativeTo(parent);
}
public void Show(Boolean visible) {
this.run();
dialog.setVisible(visible);
}
public void Close() {
dialog.setVisible(false);
}
private void setJFCFilter(String file, String ext) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(file, ext);
jfc.setFileFilter(filter);
}
private void openFile() {
File default_dir = new File(".");
jfc.setCurrentDirectory(default_dir);
setJFCFilter("Scalable Vector Graphics", "svg");
int returnVal = jfc.showOpenDialog(parentUI);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = jfc.getSelectedFile().getAbsolutePath();
String fileName = jfc.getSelectedFile().getName();
lbl_filename.setText(fileName);
lbl_path.setText(path);
load.Show(true);
createDoc(path);
load.Close();
}
}
private void createDoc(String file) {
try {
NodeList svgIDPaths;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
String xpathIDExp = "//g/#id";
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile(xpathIDExp);
svgIDPaths = (NodeList)expression.evaluate(doc, XPathConstants.NODESET);
} catch (Exception ex) {
Logger.getLogger(Loader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Edit: Use this file for testing -> svg_test.svg
I have tried calling it like this:
loader.show(true);
And also in its own thread like this:
private void load(final Boolean visible) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
loader.show(visible);
}
});
t.start();
}
Neither method works and gives me the same result, a blank dialog. I have had this issue in the past, but just gave up and removed it (loading dialog). I have tried it with a progress bar and simple text, nothing seems to work.
Also I tried it in a JOptionPane and it worked, but that's not desirable (I want to close/open when I want not via a button click).
private void load() {
ImageIcon icon = new ImageIcon(MainForm.class.getResource("/resource/loader.gif").getFile());
JOptionPane.showMessageDialog(null, "Loading...", "Loader", JOptionPane.INFORMATION_MESSAGE, icon);
}
I am aware you can't run multiple dialogs on the EDT and have to use a separate thread, but I'm using a separate thread and its not working (it works by itself).
(Also note I have one main application (frame) that is running/opening this second dialog).
Any assistance is appreciated.
You look to have a Swing threading issue where you have long-running code on the event thread messing up drawing of images, and my guess is that the long running code is in your createDoc method. Consider calling that from a background thread, such as from a SwingWorker, and calling close on your load object only after the worker has completed its work. For example something like so:
class Action1 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
openFile();
// load.Close(); // get rid of this
}
}
// .......
private void openFile() {
// ....
load.Show(true); // load dialog on event thread
new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
createDoc(path); // call this from background thread
return null;
};
protected void done() {
load.Close(); // only call this once createDoc has completed
// probably should call get() in here to catch all exceptions
};
}.execute();
}
I'm displaying some text in a JTextPane, with some syntax highlighting using an implementation of DefaultStyledDocument. This works.
Now I wanted to add a search (ctrl-F) functionality, and tried using a JXEditorPane from swingx instead of the JTextPane.
I'm doing:
p = new JXEditorPane();
p.setEditable(false);
p.setDocument(new MyStyledDocument());
p.getDocument().addDocumentListener( ... some callbacks ... );
My callbacks are called as expected. However, the text does not appear to be styled. Is this feasible ? (I noticed that only the doc in JTextPane talks about StyledDocument, the setDocument() from JTextComponent just talks about Document).
[edit] I reduced the code down to (sorry for the length, it's the best I could do):
MyStyledDocument.java:
package com.mydemo;
import java.awt.*;
import javax.swing.text.*;
public class MyStyledDocument extends DefaultStyledDocument {
private Style _style;
public MyStyledDocument() {
_style = addStyle("bluuuue", null);
StyleConstants.setBold(_style, true);
StyleConstants.setForeground(_style, new Color(0, 250, 255));
}
public synchronized void applyStyle() {
System.out.println("applyStyle");
setCharacterAttributes(0, getLength(), _style, true);
}
}
Gui.java:
package com.mydemo;
import org.jdesktop.swingx.JXEditorPane;
import javax.swing.*;
import javax.swing.event.*;
public class Gui extends JFrame {
private static final long serialVersionUID = 1L;
public Gui() {
super();
setSize(100, 100);
JEditorPane pane = new JTextPane(); // replace by new JXEditorPane() here
pane.setEditable(false);
pane.setDocument(new MyStyledDocument());
pane.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) { applyStyleInNextTick(e); }
public void removeUpdate(DocumentEvent e) { applyStyleInNextTick(e); }
public void changedUpdate(DocumentEvent e) { /* Do NOT restyle here, as this gets triggered by styling */ }
private void applyStyleInNextTick(final DocumentEvent e) {
SwingUtilities.invokeLater(new Runnable() { public void run() {
((MyStyledDocument) e.getDocument()).applyStyle();
}});
}
});
pane.setText("FooBar");
this.setContentPane(pane);
}
public static void main(String[] args) {
Gui gui = new Gui();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);
}
}
By default, the text is colored in blue. Switching to using a JXEditorPane (1 statement change) gives the same thing with the text not colored.
I am trying to make a function that allows you to navigate to a webpage. I can how to run the function, I just don't know how to write the part of the program that accesses the webpage. Here is the code that I am using to access the function via a JButton. I would like the program to work on multiple platforms. All of the solutions I have found to this, I either don't understand well enough to modify to my needs, or it isn't multi-platform.
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton google = new JButton("Google");
linux.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openURL("http://www.google.com/");
}
} );
JButton stackoverflow = new JButton("Stackoverflow");
JButton blah = new JButton("blah");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.add(linux);
panel.add(osx);
panel.add(windows);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
Yes I am aware the last two buttons do nothing.
Here is what I have tried so far:
public static void openURL(String url) {
String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Windows"))
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
else {
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape", "chrome" };
String browser = null;
for (int count = 0; count < browsers.length && browser == null; count++)
if (Runtime.getRuntime().exec(new String[] {"which", browsers[count]}).waitFor() == 0)
browser = browsers[count];
Runtime.getRuntime().exec(new String[] {browser, url});
}
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error in opening browser" + ":\n" + e.getLocalizedMessage());
}
}
Unfortunately, I don't understand what this does, or how to change it to my needs.
If possible could you explain your solution so that I can understand how it works? Thanks.
You can use Desktop class which allows Java applications to interact with default applications associated with specific file types on the host platform. Here you have a tutorial on How to integrate with the Desktop class.
Remember:
Use the isDesktopSupported() method to determine whether the Desktop
API is available
I made a quick example.
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class DesktopTest {
private JPanel panel;
public DesktopTest() {
panel = new JPanel();
ActionListener listener = new OpenUrLAction();
JButton googleButton = new JButton("google");
googleButton.setActionCommand("http://www.google.com");
googleButton.addActionListener(listener);
JButton stackOverButton = new JButton("stackOverflow");
stackOverButton.setActionCommand("http://www.stackoverflow.com");
stackOverButton.addActionListener(listener);
panel.add(googleButton);
panel.add(stackOverButton);
}
public JPanel getPanel() {
return panel;
}
private class OpenUrLAction implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (Desktop.isDesktopSupported()) {
try {
Desktop desktop = Desktop.getDesktop();
desktop.browse(new URI(e.getActionCommand()));
} catch (IOException | URISyntaxException e1) {
JOptionPane.showMessageDialog(null,
"An error happen " + e1.getMessage());
}
}
}
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("DesktopExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(Boolean.TRUE);
frame.add(new DesktopTest().getPanel());
// Display the window.
frame.pack();
frame.setVisible(Boolean.TRUE);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
If you don't find this useful , you can find some workaround in this answer
I am using a gui with JTextFields to collect some information and then a JButton that takes that infomration and writes it to a file, sets the gui visibility to false, and then uses Runnable to create an instance of another JFrame from a different class to display a slideshow.
I would like to access some of the information for the JTextFields from the new JFrame slideshow. I have tried creating an object of the previous class with accessor methods, but the values keep coming back null (I know that I have done this correctly).
I'm worried that when the accessor methods go to check what the variables equal the JTextFields appear null to the new JFrame.
Below is the sscce that shows this problem.
package accessmain;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class AccessMain extends JFrame implements ActionListener
{
private static final int FRAMEWIDTH = 800;
private static final int FRAMEHEIGHT = 300;
private JPanel mainPanel;
private PrintWriter outputStream = null;
private JTextField subjectNumberText;
private String subjectNumberString;
public static void main(String[] args)
{
AccessMain gui = new AccessMain();
gui.setVisible(true);
}
public AccessMain()
{
super("Self Paced Slideshow");
setSize(FRAMEWIDTH, FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//Begin Main Content Panel
mainPanel = new JPanel();
mainPanel.setBorder(new EmptyBorder(0,10,0,10));
mainPanel.setLayout(new GridLayout(7, 2));
mainPanel.setBackground(Color.WHITE);
add(mainPanel, BorderLayout.CENTER);
mainPanel.add(new JLabel("Subject Number: "));
subjectNumberText = new JTextField(30);
mainPanel.add(subjectNumberText);
mainPanel.add(new JLabel(""));
JButton launch = new JButton("Begin Slideshow");
launch.addActionListener(this);
mainPanel.add(launch);
//End Main Content Panel
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if(actionCommand.equals("Begin Slideshow"))
{
subjectNumberString = subjectNumberText.getText();
if(!(subjectNumberString.equals("")))
{
System.out.println(getSubjectNumber());
this.setVisible(false);
writeFile();
outputStream.println("Subject Number:\t" + subjectNumberString);
outputStream.close();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass();
testClass.setVisible(true);
}
});
}
else
{
//Add warning dialogue here later
}
}
}
private void writeFile()
{
try
{
outputStream = new PrintWriter(new FileOutputStream(subjectNumberString + ".txt", false));
}
catch(FileNotFoundException e)
{
System.out.println("Cannot find file " + subjectNumberString + ".txt or it could not be opened.");
System.exit(0);
}
}
public String getSubjectNumber()
{
return subjectNumberString;
}
}
And then creating a barebones class to show the loss of data:
package accessmain;
import javax.swing.*;
import java.awt.*;
public class AccessClass extends JFrame
{
AccessMain experiment = new AccessMain();
String subjectNumber = experiment.getSubjectNumber();
public AccessClass()
{
System.out.println(subjectNumber);
}
}
Hardcoding the accessor method with "test" like this:
public String getSubjectNumber()
{
return "test";
}
Running this method as below in the new JFrame:
SelfPaceMain experiment = new SelfPaceMain();
private String subjectNumber = experiment.getSubjectNumber();
System.out.println(subjectNumber);
Does cause the system to print "test". So the accessor methods seem to be working. However, trying to access the values from the JTextFields doesn't seem to work.
I would read the information from the file I create, but without being able to pass the subjectNumber (which is used as the name of the file), I can't tell the new class what file to open.
Is there a good way to pass data from JTextFields to other classes?
pass the argument 'AccessMain' or 'JTextField' to the second class:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass(AccessMain.this); //fixed this
testClass.setVisible(true);
}
});
Then reading the value of 'subjectNumber'(JTextField value) from the 'AccessMain' or 'JTextField' in the second class:
public class AccessClass extends JFrame
{
final AccessMain experiment;
public AccessClass(AccessMain experiment)
{
this.experiment = experiment;
}
public String getSubjectNumber(){
return experiment.getSubjectNumber();
}
}
Also, you should try Observer pattern.
A simple demo of Observalbe and Observer
Observable and Observer Objects
I am new to LWUIT, and even though I am finding it very interesting to use, I have been having the challenge of previewing whatever MIDlet I generate. Each time i run the MIDlet in an emulator, I get an ArrayOutOfBOundException displaying as a form on the screen of the emulator and will only leave after pressing OK on the form.
This is my code
import javax.microedition.midlet.*;
import com.sun.lwuit.*;
import com.sun.lwuit.events.*;
import com.sun.lwuit.Form;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
import java.io.IOException;
public class Ruwwa extends MIDlet implements ActionListener {
public void startApp() {
Display.init(this);
Form f = new Form("");
f.setTitle("Mairuwa Portal");
Label bottomText = new Label();
bottomText.setText("Welcome to the Mairuwa Portal");
bottomText.setTextPosition(Component.CENTER);
f.addComponent(bottomText);
Command exitCommand = new Command("Exit");
f.addCommand(exitCommand);
f.addCommandListener(this);
f.show();
try {
Resources r = Resources.open("/res/working.res");
UIManager.getInstance().setThemeProps(r.getTheme("Mairuwa Theme"));
} catch (IOException ioe) {
// Do something here.
}
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ev) {
Label label = new Label();
label.setText("Initiating IO, please wait...");
Display.getInstance().invokeAndBlock(new Runnable() {
public void run() {
// perform IO operation...
}
});
label.setText("IO completed!");
// update UI...
}
}
It displayed the form with this code but it didnt display it on the theme i created.The name of the theme is "working.res" and i included it in a res folder in the project folder.Thanx
While im running your code im getting illegalargumentexception on this line, bottomText.setTextPosition(Component.CENTER);.
Because you can't set the label text position as Component.CENTER. You should use the label text position as LEFT/RIGHT/BOTTOM/TOP. If you change the label text position as I mentioned, it will work properly.
So If you getting ArrayOutOfBOundException, you did a mistake on some other place. Try to debug your application and find out where did you made a mistake.
Update:
Display.init(this);
try {
Resources r = Resources.open("/res/working.res");
UIManager.getInstance().setThemeProps(r.getTheme("Mairuwa Theme"));
} catch (IOException ioe) {
// Do something here.
}
// your code.