How can i remove lines from a JTextArea one by one instead of all together?
I have a JTextArea which gets appended with string results from a thread, now i would like to remove one line at a time while the thread is executing.
You first need to decide what should trigger the line removal.
Should it be the addition of a new line, so that total line number is constant. If so then you should write your code to call the line removal code in the same location that where a new line is added.
Or should it be at a constant rate -- and if so, then you will want to use a Swing Timer for this.
Then you need to decide which line to remove. If not the first line, then you'll need to figure out how to calculate which line. The javax.swing.text.Utilities class can help you find out the start and finish location of every line of text in your JTextArea.
Edit
You ask:
the main concern is about how to remove it from the JTextArea, i have already calculated the start and end positions of a line that has to be deleted.But what function can assist in removing just that one line?
You would first get the JTextArea's Document by calling, getDocument()
Then you could call remove(int offs, int length) on the Document as per the Document API.
Try This :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SwingControlDemo {
String [] m;
int i=0;
String append="";
private JFrame mainFrame;
private JLabel headerLabel;
private JLabel statusLabel;
private JPanel controlPanel;
Timer t;
public SwingControlDemo(){
prepareGUI();
}
public static void main(String[] args){
SwingControlDemo swingControlDemo = new SwingControlDemo();
swingControlDemo.showTextAreaDemo();
}
private void prepareGUI(){
mainFrame = new JFrame("Java Swing Examples");
mainFrame.setSize(400,400);
mainFrame.setLayout(new GridLayout(3, 1));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
headerLabel = new JLabel("", JLabel.CENTER);
statusLabel = new JLabel("",JLabel.CENTER);
statusLabel.setSize(350,100);
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
mainFrame.add(headerLabel);
mainFrame.add(controlPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
}
private void showTextAreaDemo(){
headerLabel.setText("Control in action: JTextArea");
JLabel commentlabel= new JLabel("Comments: ", JLabel.RIGHT);
final JTextArea commentTextArea =
new JTextArea("This is a Swing tutorial "
+"\n to make GUI application in Java."+"\n to make GUI application in Java"+"\n to make GUI application in Java",5,20);
JScrollPane scrollPane = new JScrollPane(commentTextArea);
JButton showButton = new JButton("Show");
showButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s=commentTextArea.getText();
m=s.split("\n");
t.start();
}
});
t=new Timer(1000,new ActionListener(){
public void actionPerformed(ActionEvent e)
{
i++;
append="";
if(i<=m.length)
{
for(int j=i;j<m.length;j++)
{
append=append+m[j];
}
commentTextArea.setText(append);
}
else
{
t.stop();
}
}});
controlPanel.add(commentlabel);
controlPanel.add(scrollPane);
controlPanel.add(showButton);
mainFrame.setVisible(true);
}
}
Related
I'm trying to use the JButton count to count the number of characters entered into the JTextField t. I'm new to Java and GUIs but here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 extends Frame implements ActionListener{
TextField t;
Button count;
int a;
Choice choice;
public GUI1(){
this.t = new TextField("", 30);
this.count = new Button("count");
this.count.addActionListener(this);
JTextField x = new JTextField();
x.setEditable(false);
this.setTitle("Character count");
this.setLayout(new FlowLayout());
this.add(x);
this.add(t);
this.add(count);
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()== this.count)
t.setText(choice.getSelectedItem()+ " " +a);
}
I'm also trying to enter the value in another uneditable JTextField x. Any help is appreciated.
Add this to your code
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
a = t.getText().length();
}
});
OR
You can use lambda expression like this
count.addActionListener(e -> a = t.getText().length());
For More
http://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html
You need to add a listener
TextField t = new TextField();
Button b = new Button("Count");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
}
});
You can read more about here
http://www.tutorialspoint.com/awt/awt_button.htm
First of all, I recommend you not to use AWT elements, since it brings tons of problems and it has little to no support, instead you can try using Swing components which are a replacement/fix for AWT. You can read more about here. You might also want to read AWT vs Swing (Pros and Cons).
Now going into your problem:
You should avoid extending from JFrame, I might recommend you to create a new JFrame object instead. Here's the reason to why. That being said, you can also remove all your this.t and other calls with this.
I'm glad you're using a Layout Manager!
And now to count the number of characters on your JTextField and set text to your other JTextField you should use this code:
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
Also I fixed your code, I changed AWT elements to Swing ones and added number of cols to your second JTextField so it would appear.
So, here's a running example that I made from your code (And removed Choice choice line since you didn't posted that code):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GUI1 {
JTextField t;
JButton count;
int a;
JFrame frame;
public GUI1(){
frame = new JFrame();
t = new JTextField("", 15);
count = new JButton("count");
JTextField x = new JTextField("", 15);
x.setEditable(false);
count.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int count = t.getText().length();
System.out.println(count);
x.setText(t.getText());
}
});
frame.setTitle("Character count");
frame.setLayout(new FlowLayout());
frame.add(x);
frame.add(t);
frame.add(count);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main (String args[]) {
new GUI1();
}
}
When you click on a button you should
String str = t.getText(); // get string from jtextfield
To save the text from the texfield. Then you can use something like:
a = str..length(); // get length of string
x.setText(str + " " + a); //set it to the field
To set it to the JTextField.
I have a text game which has buttons. When a button is clicked, text appears. My text appears inside a jPanel, which is inside a jScrollPane. I would like my jPanel to automatically make more vertical space for my lines of text to be added. I have been doing it by hand but it is a lot more time consuming. Is there anyway to do this, or maybe pack a jPanel somehow. I am pretty new to this so if any extra information is needed for you to help me out feel free to ask. Thanks.
I would use a component that can do this automatically -- a JTextArea. It will automatically enlarge as more text is added.
If you need more specific help or a code example, please post your own small compilable and runnable test example program, and I can try to modify it.
You state:
I don't want to use a JTextArea because I don't want the user to be able to highlight or delete any of the text that was there in the first place.
No problem. Just make the JTextArea non-focusable and non-editable.
I have been using jLabels which are equal to "" and when a button is pressed, that jLabel is given a new value.
Try something like this:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class AddNewLines extends JPanel {
private JTextArea textArea = new JTextArea(10, 15);
private JButton addLineBtn = new JButton(new AddLineAction("Add Line", KeyEvent.VK_A));
public AddNewLines() {
textArea.setEditable(false);
textArea.setFocusable(false);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setOpaque(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
add(addLineBtn);
}
class AddLineAction extends AbstractAction {
private int count = 0;
public AddLineAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
if (count != 0) {
textArea.append("\n");
}
textArea.append("Line of Text: " + count);
count++;
}
}
private static void createAndShowGui() {
AddNewLines mainPanel = new AddNewLines();
JFrame frame = new JFrame("Add New Lines");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have created a form on which two components are present, button and progressbar (Netbeans drag and drop).Form contains the main method from where my application starts.I have created another class as well in which i have written a function.What i want is that when i press a button the application goes into the function and the progressbar runs simultaneously with it and when that function is complete with its functionality the the progress bar shows 100% complete.Now this function can take anytime for its completion so i cannot set the max value for the progressbar.So, what to do in this case?Can anyone please provide me with a good example .
JProgressBar.setIndeterminate(true)
Since what sort of a work you are doing inside that so called "Called Function", so it's tough to say, what you want in the scenario, though you can put your lines like progressBar.setValue(someProgress); at regular intervals with it's Indeterminate State to true, and at the end of the function you can simply say that progressBar.setValue(100); and the Indeterminate State will turn to false here, so that it can show that to the end user.
Have a look at this sample program :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ProgressExample
{
public static JProgressBar progressBar;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Progress Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
JButton button = new JButton("START");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
progressBar.setIndeterminate(true);
WorkingDialog wd = new WorkingDialog();
wd.createAndDisplayDialog();
}
});
contentPane.add(progressBar, BorderLayout.PAGE_START);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ProgressExample().createAndDisplayGUI();
}
});
}
}
class WorkingDialog extends JDialog
{
private String message = "HelloWorld";
private int count = 0;
private JTextField tfield;
private Timer timer;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (count == 10)
{
timer.stop();
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
dispose();
return;
}
tfield.setText(tfield.getText() + message.charAt(count));
count++;
}
};
public void createAndDisplayDialog()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
JPanel panel = new JPanel();
tfield = new JTextField(10);
panel.add(tfield);
add(panel);
pack();
setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
}
So , it seems like you are write
ProgressExample.progressBar.setIndeterminate(false);
ProgressExample.progressBar.setValue(100);
ProgressExample.progressBar.setStringPainted(true);
after your while loop.
You can take a look at my answer in a previous SO question, which contains a sample using a JProgressBar which gets updates from another Thread by using a SwingWorker. Whether or not to use a SwingWorker depends a bit on your use case. If the function take some time to run you better use the SwingWorker to avoid blocking the UI.
I need to clean my labelResult each time on textField Action, but on the first time it adds 'null' in front of string and then - prints new string right after. Please help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Frame extends JFrame implements ActionListener {
boolean isDirect = true;
String[] typeStr = {"direct", "invert"};
JLabel labelTip = new JLabel("Choose 'direct' OR 'invert' to print your next line in direct order or inverted respectively.");
JTextField textField = new JTextField("Some text!", 40);
JComboBox comboBox = new JComboBox(typeStr);
EventProcessing eventProcessing = new EventProcessing();
JLabel labelResult = new JLabel();
public Frame() {
setLayout(new BorderLayout());
getContentPane().add(labelTip, BorderLayout.PAGE_START);
getContentPane().add(comboBox, BorderLayout.CENTER);
getContentPane().add(textField, BorderLayout.AFTER_LINE_ENDS);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textField.addActionListener(this);
pack();
}
public void actionPerformed(ActionEvent e) {
getContentPane().remove(labelResult);
labelResult = new JLabel();
labelResult.setText("");
if (!(comboBox.getSelectedItem()).equals("direct")) {
isDirect = false;
}
else {
isDirect = true;
}
labelResult.setText(eventProcessing.action(isDirect, textField.getText()));
getContentPane().add(labelResult, BorderLayout.PAGE_END);
pack();
}
}
#Tim I know that in official tutorial about JComboBox is used ActionListener, but for any of actions from JComboBox to the GUI is better look for ItemListener, there you are two states (always be called twice, but you can filtering between thes two options SELECTED / DESELECTED by wraping to the if ... else)
and your code should be only
Runnable doRun = new Runnable() {
#Override
public void run() {
labelResult.setText(eventProcessing.action(isDirect, textField.getText()));
add(labelResult, BorderLayout.PAGE_END);
//1) this.pack(); if you want to re-layout with effect to size of JFrame too
//2a revalidate();
//2b plus in most cases
//2b repaint(); relayout Container with fitting JComponents inside Container,
//2b but without resize of JFrame
}
};
SwingUtilities.invokeLater(doRun);
Without the code to EventProcessing.action() it's hard to determine, but I would guess you attempt to concatenate two strings, the first of which is null. Null strings get converted to the literal string "null."
I want to delete selected text in a text area using Java Swing, but I couldn't find a way to do that. At some point I thought of using textArea.setText(""); but, when I do, it clears out everything. Can some one please help me with this?
Here is the code I've written so far,
public class DeleteTest extends JFrame implements ActionListener {
JPanel panel;
JTextArea textArea;
JButton button;
public DeleteTest() {
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground(getBackground().BLACK);
textArea = new JTextArea(300, 300);
button = new JButton("clear");
button.addActionListener(this);
panel.add(button);
add(textArea, BorderLayout.CENTER);
add(panel, BorderLayout.SOUTH);
}
#Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource()==button){
String selected=textArea.getSelectedText();
if(!selected.equals("")){
}
}
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
DeleteTest de = new DeleteTest();
}
};
SwingUtilities.invokeLater(r);
}
}
txtArea.replaceSelection("");
this should be shorter and more effective.
If you wanna remove only selected text then try this:
textArea.setText(textArea.getText().replace(textArea.getSelectedText(),""));
Hope this helps.
For JavaFx TextArea you can use deleteText(IndexRange range) method to delete the selected text.
textArea.deleteText(textArea.getSelection());
To delete text based on index use deleteText(int start, int end) overloaded method
textArea.deleteText(startIndex, endIndex);
We can use replaceSelection(String replacement) method to delete the text, in fact deleteText internally uses replaceText method but deleteText method will improve the readability of the code.