What I am doing:
I have a piece of code in which I am getting the runnable path and setting it to a label on button click for testing purpose to successfully get the running jar path at runtime.
Problem:
When running through eclipse debug or run mode, I am getting the path in the label but when I export the code to a jar file, nothing is happening on button click.
Code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.File;
import java.net.URISyntaxException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class TestProject extends JFrame {
private JPanel contentPane;
static JLabel lblNewLabel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestProject frame = new TestProject();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TestProject() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
setContentPane(contentPane);
lblNewLabel = new JLabel("New label");
contentPane.add(lblNewLabel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
getJarFileRunningPath();
}
});
contentPane.add(btnNewButton, BorderLayout.SOUTH);
}
public static String getJarFileRunningPath()
{
String currentPath = null;
try
{
File currentFilePath = new File(TestProject.class.getProtectionDomain().
getCodeSource().getLocation().toURI().getPath());
currentPath = currentFilePath.getAbsolutePath();
lblNewLabel.setText(currentPath);
}
catch (URISyntaxException e)
{
}
return currentPath;
}
}
Update:
I found out somehow that "File currentFilePath = new File..." line is getting stuck, not throwing exception also.
Thanks in future, for any help. :-)
I took your code to check your problem but the code works fine with me.
The generated jar shows me the path in the label.
I think your problem is not a coding problem.
Related
I am trying to toggle the visibility of JLable and JPanel. Both are in initial case in visible state. After pressing a Button, they should be invisible for two seconds. After this time they are going to be visible again. In adddition, there are two checkBoxes on the JPanel, which are grouped by ButtonGroup. The selection should be cleared after pressing the Button.
For solving I wrote the following code:
package Aufgaben;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EmptyBorder;
public class Aufgabe1 extends JFrame {
private JPanel contentPane;
private JPanel checkPanel;
private JPanel pointPanel;
private JRadioButton rdbtnJa;
private JRadioButton rdbtnNein;
private ButtonGroup btnGroup;
private JButton btnStart;
private JLabel lblX;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Aufgabe1 frame = new Aufgabe1();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Aufgabe1() {setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 300);
contentPane = new JPanel();
setContentPane(contentPane);
contentPane.setLayout(null);
btnStart = new JButton("Start");
btnStart.setBounds(0, 0, 684, 23);
contentPane.add(btnStart);
checkPanel = new JPanel();
checkPanel.setBounds(0, 229, 684, 33);
contentPane.add(checkPanel);
btnGroup = new ButtonGroup();
rdbtnJa = new JRadioButton("Ja");
checkPanel.add(rdbtnJa);
btnGroup.add(rdbtnJa);
rdbtnNein = new JRadioButton("Nein");
checkPanel.add(rdbtnNein);
btnGroup.add(rdbtnNein);
pointPanel = new JPanel(new BorderLayout());
pointPanel.setBackground(Color.BLACK);
pointPanel.setBounds(0, 23, 684, 209);
contentPane.add(pointPanel);
lblX = new JLabel("X");
lblX.setForeground(Color.WHITE);
lblX.setVerticalAlignment(JLabel.CENTER);
lblX.setHorizontalAlignment(JLabel.CENTER);
pointPanel.add(lblX, BorderLayout.CENTER);
run();
}
public void run() {
System.out.println("----------");
System.out.println("Method run()");
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("btn actionPerformed()");
createLightPoint();
}
});
}
private void createLightPoint() {
System.out.println("----------");
System.out.println("Method createLightPoint()");
btnGroup.clearSelection();
lblX.setVisible(false);
// lblX.repaint();
// pointPanel.repaint();
checkPanel.setVisible(false);
// checkPanel.repaint();
System.out.println("Bevor Sleep");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("After Sleep");
lblX.setVisible(true);
// lblX.repaint();
checkPanel.setVisible(true);
// checkPanel.repaint();
}
}
As you can see I tried to solve the problems (what I described above) over the function .setVisibility() as well .repaint(). I tried the functions .show() and .hide althought they are deprecatet as well.But in any case, it doesn't work.
I already read the following posts:
Show/Hide JLabel with button?
https://softwareengineering.stackexchange.com/questions/233068/is-better-show-hide-or-setvisiblebool-visible
But none of them could help the solve my problem.
I hope you can Help me.
Don't use sleep() on Event Dispatch Thread - it will prevent the thread from processing painting and other UI related events and the UI will become frozen. See The Event Dispatch Thread tutorial for more details.
You can use Swing timer instead, see How to Use Swing Timers tutorial for examples.
I wanna create a simple java application, and I have some problems.
This is my main class:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MainWindow {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("First B");
panel.add(btnNewButton);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SecWindow SW = new SecWindow();
//-----
}
});
}
}
Secound class:
import javax.swing.JButton;
import javax.swing.JPanel;
public class SecWindow {
public SecWindow() {
SecPanel();
}
public void SecPanel() {
JPanel panel2 = new JPanel();
JButton btnNewButton_2 = new JButton("Sec B");
panel2.add(btnNewButton_2);
}
}
How can I do this: when I press the "First B" I wanna delete the first panel and create a new one class SecWindow().
How can I do this: when I press the "First B" I wanna delete the first panel and create a new one class SecWindow().
You should be using a CardLayout. The CardLayout will allow you to swap panels in the frame.
Read the section from the Swing tutorial on How to Use CardLayout for more information and working examples.
The example uses a combo box to swap the panels so you just need to move that code to the ActionListener of your button.
try{
secWindow secondWindow = new secWindow();
secondWindow.frame.setVisible(true);
window.frame.setVisible(false);
} catch (Exception e) {
e.printStackTrace();
This will hide first window and show second one.
You can not completely "delete" object that has main method in it. your app will start and end in main method.
instead you can make new class and transfer main method over there
I'm working on this project and I need it run as an applet and an application. This is what I have but I stuck on where to go because I can't find anything on the internet. Are there any resources or does someone have some quick advice to give me?
public class Project extends JApplet {
public void init() {
try {
URL pictureURL = new URL(getDocumentBase(), "sample.jpg");
myPicture = ImageIO.read(pictureURL);
myIcon = new ImageIcon(myPicture);
myLabel = new JLabel(myIcon);
} catch (Exception e) {
e.printStackTrace();
}
add(label, BorderLayout.NORTH);
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
FileInputStream FIS = new FileInputStream("sample.mp3");
player = new Player (FIS);
player.play();
} catch (Exception e1) {
e1.printStackTrace();
}}});
}
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.getContentPane().add();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea("Bio");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
private Player player;
}
When trying to run something as an applet and as an application, there are several caveats.
Applets have a certain life cycle that must be obeyed. One can add the applet to the content pane of the JFrame and manually call init(), but in general, if the applet expects its start() or stop() methods to be called, things may become tricky...
More importantly: The way how resources are handled is different between applets and applications.
Handling files in applets (e.g. with a FileInputStream) may have security implications, and will plainly not work in some cases - e.g. when the applet is embedded into a website. (Also see What Applets Can and Cannot Do).
Conversely, when running this as an application, calling getDocumentBase() does not make sense. There simply is no "document base" for an application.
Nevertheless, it is possible to write a program that can be shown as an Applet or as an Application. The main difference will then be whether the main JPanel is placed into a JApplet or into a JFrame, and how data is read.
One approach for reading data that works for applets as well as for applications is via getClass().getResourceAsStream("file.txt"), given that the respective file is in the class path.
I hesitated a while, whether I should post an example, targeting the main question, or whether I should modify your code so that it works. I'll do both:
Here is an example that can be executed as an Applet or as an Application. It will read and display a "sample.jpg". (This file is currently basically expected to be "in the same directory as the .class-file". More details about resource handling, classpaths and stream handling are beyond the scope of this answer)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class AppletOrApplicationExample extends JApplet
{
#Override
public void init()
{
add(new AppletOrApplicationMainComponent());
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
frame.getContentPane().add(new AppletOrApplicationMainComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class AppletOrApplicationMainComponent extends JPanel
{
public AppletOrApplicationMainComponent()
{
super(new BorderLayout());
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
add(new JLabel("Resource not found"), BorderLayout.NORTH);
}
else
{
try
{
BufferedImage image = ImageIO.read(stream);
add(new JLabel(new ImageIcon(image)), BorderLayout.NORTH);
}
catch (IOException e1)
{
add(new JLabel("Could not load image"), BorderLayout.NORTH);
}
}
JTextArea textArea = new JTextArea("Text...");
add(textArea, BorderLayout.CENTER);
JButton button = new JButton("Button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
doSomething();
}
});
add(button, BorderLayout.SOUTH);
}
private void doSomething()
{
System.out.println("Button was clicked");
}
}
And here is something that is still a bit closer to your original code. However, I'd strongly recommend to factor out the actual application logic as far as possible. For example, your main GUI component should then not be the applet itself, but a JPanel. Resources should not be read directly via FileInputStreams or URLs from the document base, but only from InputStreams. This is basically the code that you posted, with the fewest modifications that are necessary to get it running as an applet or an application:
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Module5Assignment2 extends JApplet
{
public void init()
{
try
{
InputStream stream = getClass().getResourceAsStream("sample.jpg");
if (stream == null)
{
System.out.println("Resource not found");
}
else
{
myPicture = ImageIO.read(stream);
icon = new ImageIcon(myPicture);
label = new JLabel(icon);
add(label, BorderLayout.NORTH);
}
}
catch (Exception e)
{
e.printStackTrace();
}
add(bio);
add(bio, BorderLayout.CENTER);
pane.add(play);
getContentPane().add(pane, BorderLayout.SOUTH);
play.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileInputStream FIS = new FileInputStream("sample.mp3");
// player = new Player (FIS);
// player.play();
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
});
}
public static void main(String args[])
{
JFrame frame = new JFrame("");
// ******PRETTY SURE I NEED TO ADD SOMETHING HERE*************
Module5Assignment2 contents = new Module5Assignment2();
frame.getContentPane().add(contents);
contents.init();
// *************************************************************
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.show();
}
private JPanel pane = new JPanel();
private TextArea bio = new TextArea(
"This is the bio of Christian Sprague; he doesn't like typing things.");
private JButton play = new JButton("Play");
private Image myPicture;
private ImageIcon icon;
private JLabel label;
// private Player player;
}
let's say I have a JButton called "Play", and when I click this, it should launch C:/play.exe. How do I manage to do this? I'd love to see an example.
Take a look at the javadoc for ProcessBuilder which contains an example of how to create a process on the underlying system.
From there it's a simple matter of hooking it up to the button's ActionEvent
Have a look at the Runtime.getRuntime().exec() method. See this example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
public class Main extends JFrame {
public Main() throws HeadlessException {
setSize(200, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel label = new JLabel("Click here: ");
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
Process process = null;
System.exit(0);
try {
process = Runtime.getRuntime().exec("C:/play.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public static void main(String[] args) {
new Main().setVisible(true);
}
}
I have one JFrame that's not actively rendered, a la standard basic Swing applications, which I need to launch another JFrame when a button is clicked. The second JFrame is actively rendered using Swing's BufferStrategy, and runs on its own independently - however, when I call it from the other JFrame's ActionPerformed both JFrames freeze.
I know there are complications in using Swing to accomplish this kind of behavior - how can I get around them?
You might be able to adapt this Swing based Launcher that uses
ProcessBuilder to run programs in a separate JVM.
package gui;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* #see http://stackoverflow.com/a/5696404/230513
*/
public class Launcher extends JPanel implements Runnable {
private final JLabel label = new JLabel();
private final JButton launch = new JButton();
ProcessBuilder pb = new ProcessBuilder(
"java", "-cp", "build/classes", "gui.Launcher$DialogTest");
private volatile Process proc;
public static void main(String[] args) {
EventQueue.invokeLater(new Launcher()::createGUI);
}
private void createGUI() {
final JFrame frame = new JFrame();
frame.setLayout(new GridLayout(0, 1));
frame.add(new Launcher());
frame.add(new Launcher());
frame.add(new Launcher());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public Launcher() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
launch.setAlignmentX(0.5f);
label.setAlignmentX(0.5f);
launch.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (proc == null) {
launch.setText("Terminate");
label.setText("Status: run");
new Thread(Launcher.this).start();
} else {
proc.destroy();
reset();
}
}
});
this.add(launch);
this.add(label);
reset();
}
#Override
public void run() {
try {
proc = pb.start();
proc.waitFor();
} catch (IOException | InterruptedException ex) {
ex.printStackTrace(System.err);
}
EventQueue.invokeLater(this::reset);
}
private void reset() {
proc = null;
launch.setText("Launch");
label.setText("Status: idle");
}
private static class DialogTest {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Running",
"Test", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
});
}
}
}
Updated to Java 8 at the author's request.