I'm looking to create a seperate window in my java program to basically display the things that I print using println(). It would be nice to have some way of making certain text read and/or bold if it starts with "error:". Is there an easy or straight forward way to doing this?
A simple way would be to write a function that takes a String as an argument and then 1) prints to console using System.out.print*(), followed by printing or copying over text to that window's JTextField, or a constructor, or whatever method you are using to print text in that window, i.e.:
public method printAndCopyText(String text) {
System.out.println(text);
otherWindowObject.getTextFieldObject().setText(text);
}
Here is a sample
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
public class JConsole {
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("JConsole");
JTextPane jta = new JTextPane();
JButton button = new JButton("Run");
frame.setLayout(new BorderLayout());
frame.add(button,BorderLayout.NORTH);
frame.add(jta,BorderLayout.CENTER);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
new SwingWorker<Void, Object>(){
#Override
protected Void doInBackground() throws Exception {
outputTest("inner");
return null;
}}.execute();
}});
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
console(jta);
}
public static void outputTest(String msg){
for(int i=0;i<10;i++){
System.out.println(i+" "+msg);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public static void console(final JTextPane area) throws IOException {
area.setContentType("text/html");
final PipedInputStream outPipe = new PipedInputStream();
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
Scanner s = new Scanner(outPipe);
while (s.hasNextLine()){
String line = s.nextLine();
publish(line + "\n");
}
return null;
}
#Override
protected void process(List<String> chunks) {
for (String line : chunks){
area.setText("<font size=\"3\" color=\"red\">"+line+"</font>");
}
}
}.execute();
}
}
Related
I'm having some trouble getting an image drawn in java. There are no console errors and it prints 'drawing'. I believe I am loading the image wrong but I can't figure out the right way. If someone could tell me the correct way that would be great.
package platformer;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.util.List;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.awt.Image;
public class test2 extends JPanel implements KeyListener, ActionListener {
int Width = 1000;
int Height = 600;
private static Image offScreenBuffer;// needed for double buffering graphics
private Graphics offScreenGraphics;// needed for double buffering graphics
private BufferedImage[] img = new BufferedImage[1];
public test2() {
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(img[0],0,0,null);
}
public void timer1() {
int delay = 30; // milliseconds
new Timer(delay, this).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent evt) {
}
public static void main(String args[]) throws InterruptedException, Exception {
test2 test2 = new test2();
JFrame frame = new JFrame("platformer");
frame.setSize(test2.Width, test2.Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.green);
frame.add(test2);
frame.setResizable(false);
frame.addKeyListener(test2);
test2.init();
test2.timer1();
// What to do after the program starts
while (true) {
test2.repaint();
}
}
public void init() {
try {
URL url = new URL("platform.png");
img[0] = ImageIO.read(url);
} catch (IOException e) {
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
Swing has an infinite loop that does event handling for you. You don't need the while(true) loop. You should call frame.setVisible(true) after all of your UI is configured. I mean that it should be the last thing in main(). Also, you should do this on the UI thread with
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
So main() should look like
public static void main(String args[]) throws InterruptedException, Exception {
test2 test2 = new test2();
JFrame frame = new JFrame("platformer");
frame.setSize(test2.Width, test2.Height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.green);
frame.add(test2);
frame.setResizable(false);
frame.addKeyListener(test2);
test2.init();
test2.timer1();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
}
However, the main problem is the try... catch in init() which ignores exceptions. You should never leave a catch empty. At the very least you should print a stacktrace. Better yet, add the appropriate exceptions to the methods throws clause like this:
public void init() throws IOException {
URL url = new URL("platform.png");
img[0] = ImageIO.read(url);
}
Note if a problem occurs, you will know about it immediately.
Anyone can tell me why TryGraphic freeze the JFrame with a scanner in the first main()? If I remove the Scanner or if I execute the code directly, all works. (The original "Try" class obviously do a lot of different stuff. I wrote these classes to make it simple.)
import java.util.Scanner;
public class Try {
public Try(){
}
public static void main(String[] args){
System.out.println("FOO");
String s = new Scanner(System.in).nextLine();
System.out.println(s);
}
}
This is the graphic implementation:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
public class TryGraphic extends JFrame{
/**
*
*/
private static final long serialVersionUID = 7491282237007954227L;
private JButton execute = new JButton("Esegui");
private PipedInputStream inPipe = new PipedInputStream();
private PipedInputStream outPipe = new PipedInputStream();
private JTextField tfIn = new JTextField();
private JTextArea outputArea = new JTextArea();
private PrintWriter inWriter;
public TryGraphic(){
super("TRY");
System.setIn(inPipe);
try {
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
}catch (IOException ioe){
ioe.printStackTrace();
}
tfIn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
String text = tfIn.getText();
tfIn.setText("");
inWriter.println(text);
}
});
this.add(execute,BorderLayout.SOUTH);
this.add(new JScrollPane(outputArea),BorderLayout.CENTER);
this.add(tfIn, BorderLayout.NORTH);
execute.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
SwingWorker<Void,String> worker = new SwingWorker<Void, String>() {
protected Void doInBackground() throws Exception {
Scanner s = new Scanner(outPipe);
while (s.hasNextLine()) {
String line = s.nextLine();
publish(line);
}
return null;
}
#Override
protected void process(java.util.List<String> chunks) {
for (String line : chunks){
outputArea.append(line+System.lineSeparator());
outputArea.validate();
}
}
};
worker.execute();
Try.main(new String[]{""});
}
});
this.setSize(300,300);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new TryGraphic();
}
}
You're blocking the GUI Event Dispatch Thread. You need to spawn a separate thread to wait for input so you can keep your GUI responsive.
You're already doing the right thing by creating a SwingWorker to handle I/O in your TryGraphic class. You should do something similar to move the Try.main(new String[]{""}); call off the Event Dispatch Thread, which will keep your JFrame from locking up.
I am trying to get a progress bar to accurately reflect my SwingWorker. But I really can't figure out how to do it. I got the bar to just do a static animation until the operation has completed but I want a real active bar.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package frglauncher;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
*
* #author KYLE-LAPTOP
*/
class DownloadWorker extends SwingWorker<String, Object> {
private String game;
private JProgressBar bar;
private JLabel label;
public DownloadWorker(JProgressBar bar, String game, JLabel label) {
this.game = game;
this.bar = bar;
this.label = label;
}
#Override
public String doInBackground() {
// Download here
label.setText("test");
try {
// ProgressBar/Install
System.out.println("FILELOCATION:\n----------");
String URL_LOCATION = "http://www.futureretrogaming.tk/gamefiles/ProfessorPhys.jar";
String LOCAL_FILE = ("\\" + game + "\\");
File localfile = new File(LOCAL_FILE);
if (localfile.exists()) {
System.out.println("Directory exists!");
}
else {
System.out.println("Directory doesn't exist! Creating...");
localfile.mkdir();
if (localfile.exists()) {
System.out.println("Directory created!");
}
}
System.out.println("LOCALFILE:\n-------");
System.out.println(LOCAL_FILE);
URL website = new URL(URL_LOCATION);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(LOCAL_FILE + "\\ProfessorPhys.jar\\");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
System.out.println("--------\nDone Downloading\n---------");
RandomAccessFile randomAccessFile = null;
File file = new File(LOCAL_FILE + "ProfessorPhys.jar\\");
JarFile jar = new JarFile(file);
Enumeration enum1 = jar.entries();
while (enum1.hasMoreElements()) {
JarEntry file1 = (JarEntry) enum1.nextElement();
System.out.println("Directory to extract: " + LOCAL_FILE);
System.out.println("\n" + file1.getName() + "\n");
File f = new File(file1.getName());
if (file1.isDirectory()) { // If it's a directory, create it
f.mkdir();
continue;
}
try (InputStream is1 = jar.getInputStream(file1)) {
FileOutputStream fos1 = new FileOutputStream(f);
while (is1.available() > 0) { // Write contents of 'is' to 'fos'
fos1.write(is1.read());
}
fos1.close();
}
}
}
catch (FileNotFoundException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
catch (MalformedURLException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(DownloadWorker.class.getName()).log(Level.SEVERE, null, ex);
}
return "done";
}
#Override
protected void done() {
// Done
label.setText("Download of " + game + "is done.");
System.exit(0);
}
}
Several things:
There are four rules to follow with SwingWorker. You can refer to this diagram: .
So, this code:
#Override
public String doInBackground() {
//download here
label.setText("test");
violates that rule. Your label.setText() should be moved to the constructor.
To send "updates" to Swing components (like your progress bar) you want to use the process() method, which you invoke using publish() from inside your doInBackground(). Your second SwingWorker parameter reflects the type of value you want to pass. I've attached two SSCCEs. One passes an Integer to the process() method, the other passes a String. Should give you an idea of what's going on.
SSCCE using Integer:
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
*
* #author Ryan
*/
public class Test {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
go();
}
});
}
public static void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Loading...");
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(false);
int max = 1000;
jpb.setMaximum(max);
panel.add(label);
panel.add(jpb);
frame.add(panel);
frame.pack();
frame.setSize(200,90);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Task_IntegerUpdate(jpb, max, label).execute();
}
static class Task_IntegerUpdate extends SwingWorker<Void, Integer> {
JProgressBar jpb;
int max;
JLabel label;
public Task_IntegerUpdate(JProgressBar jpb, int max, JLabel label) {
this.jpb = jpb;
this.max = max;
this.label = label;
}
#Override
protected void process(List<Integer> chunks) {
int i = chunks.get(chunks.size()-1);
jpb.setValue(i); // The last value in this array is all we care about.
System.out.println(i);
label.setText("Loading " + i + " of " + max);
}
#Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < max; i++) {
Thread.sleep(10); // Illustrating long-running code.
publish(i);
}
return null;
}
#Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
SSCCE using String:
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
*
* #author Ryan
*/
public class Test2 {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
go();
}
});
}
public static void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Loading...");
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(true);
panel.add(label);
panel.add(jpb);
frame.add(panel);
frame.pack();
frame.setSize(200,90);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Task_StringUpdate(label).execute();
}
static class Task_StringUpdate extends SwingWorker<Void, String> {
JLabel jlabel;
public Task_StringUpdate(JLabel jlabel) {
this.jlabel = jlabel;
}
#Override
protected void process(List<String> chunks) {
jlabel.setText(chunks.get(chunks.size()-1)); // The last value in this array is all we care about.
System.out.println(chunks.get(chunks.size()-1));
}
#Override
protected Void doInBackground() throws Exception {
publish("Loading Step 1...");
Thread.sleep(1000);
publish("Loading Step 2...");
Thread.sleep(1000);
publish("Loading Step 3...");
Thread.sleep(1000);
publish("Loading Step 4...");
Thread.sleep(1000);
return null;
}
#Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(jlabel.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
I want to get the event like crtl+c or right click copy in windows , that could do the event to java application running ,
that means if someone copies some text , that should be pasted into the java application textarea...
i have made the java application and it can accept arguments through main method.
but how to trigger event from windows to java..
The simplest way is to monitor changes to the Toolkit.getSystemClipboard
There are two ways to do this. You can monitor changes to the DataFlavour, but this will only help if the data flavor changes, not the content and/or you could monitor the contents of the clipboard and update your view when it's content changes...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClipboardMonitor {
public static void main(String[] args) {
new ClipboardMonitor();
}
public ClipboardMonitor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea textArea;
public TestPane() {
textArea = new JTextArea(10, 10);
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(new FlavorListener() {
#Override
public void flavorsChanged(FlavorEvent e) {
setText(getClipboardContents());
}
});
Thread t = new Thread(new ContentsMonitor());
t.setDaemon(true);
t.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected String getClipboardContents() {
String text = null;
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) {
try {
Transferable contents = clipboard.getContents(TestPane.this);
text = (String) contents.getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return text;
}
protected void setText(final String text) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textArea.setText(text);
}
});
}
public class ContentsMonitor implements Runnable {
#Override
public void run() {
String previous = getClipboardContents();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
String text = getClipboardContents();
if (text != null && !text.equals(previous)) {
setText(text);
previous = text;
}
}
}
}
}
}
I've been wondering if for example:
JTextPane chatTextArea = new JTextPane();
s.replaceAll(":\\)", emoticon());
public String emoticon(){
chatTextArea.insertIcon(new ImageIcon(ChatFrame.class.getResource("/smile.png")));
return "`";
}
can put a picture and a "`" everywhere ":)" is found. When I run it like this if s contains a ":)" then the whole s gets replaced just by the icon.
Is there a way to do it?
Here is a small example I made (+1 to #StanislavL for the original), simply uses DocumentListener and checks when a matching sequence for an emoticon is entered and replaces it with appropriate image:
NB: SPACE must be pressed or another character/emoticon typed to show image
import java.awt.Dimension;
import java.awt.Image;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.Utilities;
public class JTextPaneWithEmoticon {
private JFrame frame;
private JTextPane textPane;
static ImageIcon smiley, sad;
static final String SMILEY_EMOTICON = ":)", SAD_EMOTICON = ":(";
String[] emoticons = {SMILEY_EMOTICON, SAD_EMOTICON};
private void initComponents() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textPane = new JTextPane();
//add docuemntlistener to check for emoticon insert i.e :)
((AbstractDocument) textPane.getDocument()).addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(final DocumentEvent de) {
//We should surround our code with SwingUtilities.invokeLater() because we cannot change document during mutation intercepted in the listener.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
StyledDocument doc = (StyledDocument) de.getDocument();
int start = Utilities.getRowStart(textPane, Math.max(0, de.getOffset() - 1));
int end = Utilities.getWordStart(textPane, de.getOffset() + de.getLength());
String text = doc.getText(start, end - start);
for (String emoticon : emoticons) {//for each emoticon
int i = text.indexOf(emoticon);
while (i >= 0) {
final SimpleAttributeSet attrs = new SimpleAttributeSet(doc.getCharacterElement(start + i).getAttributes());
if (StyleConstants.getIcon(attrs) == null) {
switch (emoticon) {//check which emtoticon picture to apply
case SMILEY_EMOTICON:
StyleConstants.setIcon(attrs, smiley);
break;
case SAD_EMOTICON:
StyleConstants.setIcon(attrs, sad);
break;
}
doc.remove(start + i, emoticon.length());
doc.insertString(start + i, emoticon, attrs);
}
i = text.indexOf(emoticon, i + emoticon.length());
}
}
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
}
#Override
public void removeUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
}
});
JScrollPane scrollPane = new JScrollPane(textPane);
scrollPane.setPreferredSize(new Dimension(300, 300));
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
try {//attempt to get icon for emoticons
smiley = new ImageIcon(ImageIO.read(new URL("http://facelets.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/e/m/emoticons0001.png")).getScaledInstance(24, 24, Image.SCALE_SMOOTH));
sad = new ImageIcon(ImageIO.read(new URL("http://zambia.primaryblogger.co.uk/files/2012/04/sad.jpg")).getScaledInstance(24, 24, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JTextPaneWithEmoticon().initComponents();
}
});
}
}
References:
How to add smileys in java swing?