I'm trying to implement a JEditorPane with hyperlinks. I'm using a HyperLinkListener but it seems to never trigger.
Code:
JEditorPane editorPane = new JEditorPane("text/html", programInfo);
editorPane.addHyperlinkListener(e -> {
System.out.println("CLICK");
if (e.getEventType().equals(HyperlinkEvent.EventType.ENTERED))
try {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(e.getURL().toURI());
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
});
JOptionPane.showMessageDialog(contentPane, editorPane);
Sample HTML:
<body>
<p><b>Author:</b> James - sample</p>
</body>
This leads to this:
But when I click on the links nothing happens.
Additional Info:
I'm testing this on Ubuntu 14.04.
I have set Look and Feel to system.
EDIT: thanks to #AndrewThompson for finding the real issue.
The reason why it does not trigger events is because the editor pane will only fire events when it is not editable. So, to make your code work you should add this line after the construction of the editorPane:
editorPane.setEditable(false);
Below you can find a self contained example:
public class TestFrame extends JFrame {
public static void main(String[] args) {
JEditorPane editorPane = new JEditorPane("text/html", "test link to example.com");
editorPane.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(HyperlinkEvent e) {
System.out.println("CLICK");
if (e.getEventType().equals(HyperlinkEvent.EventType.ENTERED)) try {
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(e.getURL().toURI());
}
}
catch (IOException e1) {
e1.printStackTrace();
}
catch (URISyntaxException e1) {
e1.printStackTrace();
}
}
});
editorPane.setEditable(false); // otherwise ignores hyperlink events!
JFrame frame = new JFrame("EditorPane Example");
frame.add(editorPane);
frame.setSize(300,200);
frame.setVisible(true);
} }
(sorry, I removed the lambda because I don't have a jdk8 on this PC)
Related
I am having a problem with loading images, as I am trying to load a background for my launcher. It works when I run it in Eclipse, but when I export it to a jar file, it doesn't. I have paged through the already asked questions, No luck.
Here is my code:
public void initializeJFrame(){
ImageIcon bg = new ImageIcon("src/background.png");
jb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (jta.getText().length() < 3 || jta.getText().length() > 16) {
System.exit(-1);
} else {
try {
Runtime.getRuntime().exec(cmd, null, dir);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.exit(0);
}
}
});
jf.setSize(WIDTH,HEIGHT);
jf.setTitle("Cracked Launcher");
jf.setLayout(null);
jf.setContentPane(new JLabel(bg));
jf.setResizable(false);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.start();
My image is in the src folder, nothing else. I cannot find what the problem is.
Thanks for your support.
ImageIcon bg = new ImageIcon("src/background.png");
This constructor takes a filename; it will not load resources from a jar. You want to pass a URL generated by a classloader, like so:
ImageIcon bg = new ImageIcon(getClass().retResource("background.png"));
I have a set of JButtons, each of which opens a separate YouTube video webpage. When first running the program, I can click on any ONE button and get the video page. When I try to get another video page with a button click, it doesn't work - in fact, all the buttons are deactivated. This is the case whether or not I close the video webpage.
How can I keep all the buttons activated? Thanks in advance.
Here's the code for reference. The button links and tags are populated from a text file.
//import statements
public class VideoRecord extends JFrame {
private File videoRecordFile;
public VideoRecord() throws FileNotFoundException {
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(2,2));
setSize(new Dimension(500, 500));
videoRecordFile = new File("videorecord.txt");
getButtons();
pack();
}
public void getButtons() throws FileNotFoundException {
Scanner input = new Scanner(videoRecordFile);
while (input.hasNextLine()) {
Scanner lineInput = new Scanner(input.nextLine());
while (lineInput.hasNext()) {
final String urlString = lineInput.next();
String buttonText = lineInput.next();
JButton btn = new JButton(buttonText);
add(btn);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
URL videoURL = new URL(urlString);
URLConnection videoConnection = videoURL.openConnection();
videoConnection.connect();
openWebpage(videoURL);
}
catch (MalformedURLException mue) {}
catch (IOException ioe) {}
setEnabled(false);
}
});
}
}
}
public static void openWebpage(URI uri) {
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void openWebpage(URL url) {
try {
openWebpage(url.toURI());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws FileNotFoundException {
VideoRecord vr = new VideoRecord();
}
}
Take a second to look at you code...
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
URL videoURL = new URL(urlString);
URLConnection videoConnection = videoURL.openConnection();
videoConnection.connect();
openWebpage(videoURL);
}
catch (MalformedURLException mue) {}
catch (IOException ioe) {}
setEnabled(false);
}
});
When you click a button you call setEnabled(false);...
This has actually disable the frame, not the button that was clicked...
Try using ((JButton)e.getSource()).setEnabled(false) instead
Don't throw away you Exceptions blindly, they provide important and useful information that can help solve problems
I am new to java, I facing a problem while trying to change the look and feel of a java file when invoked from another class. I have two classes, main.java and auth.java. I have set the look and feel as nimbus in the auth.java file. When I try to invoke auth class from main.java(i have attached the code snippet below) the UI doesn't change. But when i use
public static void main(String[] args) in auth.java and try to run that file individually the UI of the jFrame changes. Kindly let me know if there is a way to change the UI of a jFrame when called from another class. And is there any problem invoking the jFrame from another class, is that a good practice? because we are onto doing a big project and will require calling authentication frame once in a while, so any suggestion guys?
Thank you all in advance! :)
main.java:
package com.package.name;
public class main {
public static void main(String[] args) {
new auth();
}
}
This is a section of my auth.java code:
package com.package.name;
import javax.swing.*;
import java.awt.*;
public class auth extends JFrame {
public auth() {
initComponents();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel ( "javax.swing.plaf.nimbus.NimbusLookAndFeel" );
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
}
});
}
You've already called initComponents before changing the look at feel. This will install what ever is the currently installed look and feel into those components.
Without having to go and instruct each component to update its UI, you could simply swap the installation of the look and feel with the initComponents method, for example...
try {
UIManager.setLookAndFeel ( "javax.swing.plaf.nimbus.NimbusLookAndFeel" );
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
initComponents();
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
Now, having said that. You really should have been within the context of the EDT before you called the auth constructor and auth shouldn't really be making decisions about the Look and Feel. What happens if you want to use this frame again with a different look and feel?
Instead could do something more like
public class main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel ( "javax.swing.plaf.nimbus.NimbusLookAndFeel" );
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
new auth();
}
});
}
}
public class auth extends JFrame {
public auth() {
initComponents();
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
}
You should also consider taking a look through Code Conventions for the Java Programming Language, it will make your code much easier to read ;)
My image was displaying properly before I had a JButton on top of it. Now that I have added a JButton to my code, my image does not display. In the ActionPerformed method I am telling the button to setVisbible(false). When I click the button, it disapears and all that is behind it is the background.
public class Main extends JFrame implements ActionListener {
public static void main(String[] args) {
Main main = new Main();
}
ImageIcon GIF = new ImageIcon("src/Zombie Steve gif.gif");
JButton button = new JButton("Click me!");
JLabel Label = new JLabel(GIF);
public Main() {
button.addActionListener(this);
Label.setHorizontalAlignment(0);
JFrame Frame = new JFrame("zombieSteveGIF");
Frame.setSize(650, 650);
Frame.setVisible(true);
Frame.add(Label);
Frame.add(button);
Frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
while (true) {
Frame.getContentPane().setBackground(Color.BLUE);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.GREEN);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Frame.getContentPane().setBackground(Color.RED);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void actionPerformed(ActionEvent e) {
button.setVisible(false);
}
}
Your problem is that you have a BorderLayout (the default for JFrames), and you are adding two components in the same position. The default is BorderLayout.CENTER, and by adding two components with just the default constraints, the first one is removed and the second put in its place.
As for fixing your problem, what do you want to achieve? If you want the components to show on top of one another, you can use the OverlayLayout. If you don't want this, try some other layout manager.
I have a JDesktopPane with this code.
public class Menu extends JFrame implements ActionListener{
/**
* Creates new form Portada
*/
public static JDesktopPane desktop;
public JDesktopPane getDesktop() {
return desktop;
}
public Menu() {
desktop = new JDesktopPane();
setContentPane(desktop);
desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
initComponents();
}
}
then i add the new components like this
desktop.add(orden);
and when i want to call them i use
if(e.getSource()==jMenuItem1_1){
orden.setVisible(true);
desktop.setSelectedFrame(orden);
desktop.moveToFront(orden);
try {
orden.setSelected(true);
} catch (PropertyVetoException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
The problem i get is that when "orden" wants to pop out another JInternalFrame i use the next code.
searchSupplier.setVisible(true);
Main.getInstance().getPortada().getDesktop().add(searchSupplier);
Main.getInstance().getPortada().getDesktop()
.moveToFront(searchSupplier);
try {
searchSupplier.setSelected(true);
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
When I execute the event more than 2 times i get the next error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position
Where should i add the new JInternalFrame to the DesktopPane? or to Orden?, or What can i do to fix this error?
If the searchSupplier frame is already on the desktop, it is unlikely that you will able to add it again. Try using getParent to determine if the frame needs to be added
if (searchSupplier.getParent() == null) {
Main.getInstance().getPortada().getDesktop().add(searchSupplier);
}
searchSupplier.setVisible(true);
Main.getInstance().getPortada().getDesktop().moveToFront(searchSupplier);
try {
searchSupplier.setSelected(true);
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}