How to find the next occurence in textarea without exceptions? - java

I've been working on project which finds the next occurrence by clicking on button of specific word, but it keeps throwing exceptions ?!
public void highlightnext(JTextComponent textareafield,String pattern) {
textareafield.getHighlighter().removeAllHighlights();
//highlighting
try {
hilit = textarea.getHighlighter();
painter = new DefaultHighlighter.DefaultHighlightPainter(HILIT_COLOR);
Document doc=textarea.getDocument();
String area=doc.getText(0, doc.getLength());
if (pos>area.length())
return;
pos=(area.toUpperCase().indexOf(pattern.toUpperCase(),pos));
pos=(area.toUpperCase().indexOf(pattern.toUpperCase(),pos+1));
hilit.addHighlight(pos,pos+pattern.length(), painter);
System.out.println(pos);
} catch (BadLocationException e) {
e.printStackTrace();
}
}

pos=(area.toUpperCase().indexOf(pattern.toUpperCase(),pos));
pos=(area.toUpperCase().indexOf(pattern.toUpperCase(),pos+1));
Don't convert the data to upper case each time that is not efficient. Convert the text once into a String and then use those two strings in your code.
Not sure why you have two statements. You only need one to do the search.
You need to check the value of "pos" to make sure it is not "-1"
Here is some example code. It finds all occurrences of the text:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextAndNewLinesTest extends JFrame
{
public TextAndNewLinesTest()
throws Exception
{
String text =
"one two three four five\r\n" +
"one two three four five\r\n" +
"one two three four five\r\n" +
"one two three four five\r\n" +
"one two three four five\r\n";
JTextPane textPane = new JTextPane();
textPane.setText(text);
JScrollPane scrollPane = new JScrollPane( textPane );
getContentPane().add( scrollPane );
Highlighter.HighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter( Color.cyan );
String search = "three";
int offset = 0;
int length = textPane.getDocument().getLength();
text = textPane.getDocument().getText(0, length);
//text = textPane.getText();
while ((offset = text.indexOf(search, offset)) != -1)
{
try
{
textPane.getHighlighter().addHighlight(offset, offset + 5, painter); // background
offset += search.length();
}
catch(BadLocationException ble) {}
}
}
public static void main(String[] args)
throws Exception
{
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new TextAndNewLinesTest();
frame.setTitle("Text and New Lines - Problem");
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.setSize(400, 120);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
If you only want to find one occurrence at a time, then basically you would change the "while" statement to an "if" statement.

Related

Layered JLabels not working

When I attempt to layer JLabels, the end result has them appearing next to each other, with the gif overlapping the logo image even though I told it to be on the bottom layer.
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.io.*;
class GameFrame extends JFrame
{
ImageIcon logo, bg;
JTextPane l1;
JTextArea l2;
JLabel i1, i2;
JButton b1;
GridBagLayout g;
int count;
JLayeredPane jlp;
GameFrame() throws IOException, UnsupportedLookAndFeelException, ClassNotFoundException, InstantiationException, IllegalAccessException
{
super("Simple2.0");
setSize(400, 250);
//setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
count = 0;
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
jlp = new JLayeredPane();
jlp.setSize(400, 250);
jlp.setVisible(false);
bg = new ImageIcon("fire.gif");
i2 = new JLabel(bg);
i2.setBackground(new Color(0, 0, 0, 0));
i2.setVisible(false);
logo = new ImageIcon("logo.png");
i1 = new JLabel(logo);
i1.setBackground(new Color(0, 0, 0, 0));
i1.setVisible(false);
g = new GridBagLayout();
GridBagConstraints gb = new GridBagConstraints();
gb.gridy = 1;
gb.insets = new Insets(10, 0, 0, 0);
gb.anchor = GridBagConstraints.SOUTH;
setLayout(g);
l1 = new JTextPane();
l1.setBackground(getBackground());
l1.setEnabled(false);
l1.setDisabledTextColor(Color.BLACK);
l1.setSize(350, 200);
l1.setText("Hello and welcome to SIMPLE!");
l2 = new JTextArea();
l2.setSize(350, 200);
l2.setBackground(getBackground());
l2.setEnabled(false);
l2.setDisabledTextColor(Color.BLACK);
l2.setLineWrap(true);
l2.setWrapStyleWord(true);
l2.setVisible(false);
b1 = new JButton("continue");
b1.addActionListener((ActionEvent e) ->
{
if(count == 0)
{
l1.setVisible(false);
l2.setText(" This game was a rework of a text based game made by me and a friend of mine during our first semester in Java.");
l2.setVisible(true);
count++;
}
else if(count == 1)
{
l2.setText(" It was a simple attempt to make a combat and inventory system that would function within a Java operated terminal, and was"
+ " full of bugs, errors, and long workarounds to problems that can now easily be solved with our new ability.");
count++;
}
else if(count == 2)
{
l2.setVisible(false);
l1.setText("And as such I present our new work, SIMPLE.");
l1.setVisible(true);
count++;
}
else
{
l1.setVisible(false);
b1.setVisible(false);
i1.setVisible(true);
i2.setVisible(true);
jlp.setVisible(true);
}
});
jlp.add(i1, 0);
jlp.add(i2, 1);
add(l1);
add(l2);
add(i1);
add(i2);
add(b1, gb);
add(jlp);
setVisible(true);
}
}
Thanks in advance for any help!
edit: I added the specific layers but have not seen a change in the outcome, as blaring a problem as that would immediately seem.
Read the section from the Swing tutorial on How to Use Layered Panes for a working example that displays multiple layers on top of one another.
When you "add" the label to the layered pane, you need to specify the "layer" you want the label added to. The tutorial explains how the layering works.
Also, while looking at the tutorial look at the better way to structure your program so that:
the GUI is created on the Event Dispatch Thread
you don't extend JFrame.
It is better to start with the working example and then customize it slowly to your requirement.

How to set different JTextArea text alignment per line?

I have a JTextArea in which i want to display messages aligned to right or left, depending on a variable I pass along with the message. Can I do that?
What did I do wrong? Nothing gers added to the text pane when i run my GUI
battleLog = new JTextPane();
StyledDocument bL = battleLog.getStyledDocument();
SimpleAttributeSet r = new SimpleAttributeSet();
StyleConstants.setAlignment(r, StyleConstants.ALIGN_RIGHT);
try {
bL.insertString(bL.getLength(), "test", r);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
Not with a JTextArea.
You need to use a JTextPane which supports different text and paragraph attributes. An example to CENTER the text:
JTextPane textPane = new JTextPane();
textPane.setText("Line1");
StyledDocument doc = textPane.getStyledDocument();
// Define the attribute you want for the line of text
SimpleAttributeSet center = new SimpleAttributeSet();
StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
// Add some text to the end of the Document
try
{
int length = doc.getLength();
doc.insertString(doc.getLength(), "\ntest", null);
doc.setParagraphAttributes(length+1, 1, center, false);
}
catch(Exception e) { System.out.println(e);}
if("left".equals(input)){
setAlignmentX(Component.LEFT_ALIGNMENT);
}
Have a try!

Can I resize only the height of my frame using pack()?

I am writing a program that brings up a JDialog box that lists multiple options from a config file. The number of options can vary each time it is opened, so I need to be able to dynamically adjust the height of the window, but not the width. The window looks best using FlowLayout and defining the width of the window so that the JPanels that the data is in wrap propertly. But I am unable to dynamically adjust the height. I tried to use the pack method, but it lines all the panels up in one line like FlowLayout is meant to be. I tried GridLayout but it re-sizes all of the panels to the same size and is an unacceptable look. I also tried BoxLayout but was unable to get that one to work.
Is there a better layout manager to use or a way to make the width static?
Here is my code. Every panel and box is defined above the constructor, I just did not copy that code:
public ReSizeMe()
{
curConfig = new Config();
config = curConfig.getConfig();
setBox = new JDialog();
setBox.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // Set as 480, 600
setBox.setLayout(new FlowLayout());
this.buildSetFrame();
//setBox.pack();
setBox.setVisible(true);
}
public void buildSetFrame()
{
intPanel = new JPanel();
butPanel = new JPanel();
optPanel = new JPanel();
editPanel = new JPanel[maxOptions];
optWrapper = new JPanel[maxOptions];
intPanel.setLayout(new FlowLayout());
optPanel.setLayout(new GridLayout(10, 1)); // trying different things here too.
optText = new JTextField[maxOptions];
editButton = new JButton[maxOptions];
delButton = new JButton[maxOptions];
intPanel.setBorder(BorderFactory.createTitledBorder("Modify Interface"));
apply = new JButton("Apply");
newOpt = new JButton("New Option");
help = new JButton("Help");
close = new JButton("Close");
intPanel.add(ethIntLabel);
intPanel.add(ethIntName);
butPanel.add(apply);
butPanel.add(newOpt);
butPanel.add(close);
ethIntName.setText(config.getProperty("EthIntName"));
setBox.add(welcomeMsg);
setBox.add(intPanel);
setBox.add(optPanel);
buildOptions();
setBox.add(butPanel);
}
void buildOptions()
{
for (int i = 0; i < maxOptions; i++)
{
editable = Boolean.parseBoolean(config.getProperty("option." + i + ".edit"));
if (config.getProperty("option." + i + ".name") == null)
{
break;
}
else if (editable != false &&
config.getProperty("option." + i + ".name") != null &&
!config.getProperty("option." + i + ".name").isEmpty())
{
editPanel[i] = new JPanel();
optWrapper[i] = new JPanel();
optText[i] = new JTextField(20);
editButton[i] = new JButton("Edit");
delButton[i] = new JButton("Delete");
editButton[i].setActionCommand(Integer.toString(i));
delButton[i].setActionCommand(Integer.toString(i));
optText[i].setText(config.getProperty("option." + i + ".name"));
optText[i].setEditable(false);
editPanel[i].add(editButton[i]);
editPanel[i].add(delButton[i]);
optWrapper[i].add(optText[i]);
optWrapper[i].add(editPanel[i]);
optPanel.add(optWrapper[i]);
}
}
}
Yes, Box should work wonderful:
Box box = Box.createVerticalBox();
box.add(...)
box.add(Box.createVerticalStrut(5)); // spacing
<etc.>
add(box);

How to check if you're on a Mac or Windows to resize GUI in Java?

I've written a program which needs to work on both Macs and Windows. In terms of the GUI it looks fine on Windows but the JFrame is too small on Mac.
I've used GridBag layout and nothing is using absolute, which has been suggested in answers similar to this problem.
I've tried using pack() but it doesn't work properly for this GUI. It doesn't even resize the frame to fit in the menu bar. I'm using setSize(X, Y) but is there a way to check to see if the user is on a Mac and then change the size accordingly?
i've also tried using setMinimumSize() and then pack() but pack doesn't do anything anyway.
Here is my frame code bit; just incase anything is wrong in there due to pack() not working.
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) { }
try {
timeCodeMask = new MaskFormatter(" ## : ## : ## : ## ");
} catch(ParseException e) {
errorMessage("Warning!", "Formatted text field hasn't worked, text fields will not be formatted.");
}
try {
activePanel = new JPanelSwapper("src/bg.png");
} catch(IOException e) {
errorMessage("Warning!", "Background image has not loaded, continuing without one.");
}
FPS = 24;
calculatorPanel = calculatorPanel();
converterPanel = converterPanel();
activePanel.setPanel(calculatorPanel());
previousTimes = new TimeStore();
resultTimes = new TimeStore();
previousConversions = new TimeStore();
frame = new JFrame("TimeCode Calculator & Converter");
ImageIcon frameIcon = new ImageIcon("src/frame icon.png");
frame.setIconImage(frameIcon.getImage());
frame.setExtendedState(JFrame.NORMAL);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setSize(WIDTH, HEIGHT);
//frame.pack();
frame.setMinimumSize(new Dimension(WIDTH, HEIGHT));
frame.pack();
frame.setResizable(false);
frame.setJMenuBar(menuBar());
frame.getContentPane().add(activePanel);
frame.setBackground(Color.WHITE);
frame.setVisible(true);
screen = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation((screen.width - WIDTH) / 2, (screen.height - HEIGHT) / 2);
Thanks in advance!
You can find out which operating system is used with system properties.
For example:
System.getProperty("os.name"); //returns name of os as string
System.getProperty("os.version"); //returns version of os as string
System.getProperty("os.arch"); //returns architecture of os as string
Check it against conditions:
public String getOS() {
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("mac") >= 0){
return "MAC";
}
else if(os.indexOf("win") >= 0){
return "WIN";
}
else if(os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0){
return "LINUX/UNIX";
}
else if(os.indexOf("sunos") >= 0){
return "SOLARIS";
}

Multiline JLabels - Java [duplicate]

This question already has answers here:
Multiline text in JLabel
(11 answers)
Closed 8 years ago.
I want JLabel text in multiline format otherwise text will be too long. How can we do this in Java?
If you don't mind wrapping your label text in an html tag, the JLabel will automatically word wrap it when its container's width is too narrow to hold it all. For example try adding this to a GUI and then resize the GUI to be too narrow - it will wrap:
new JLabel("<html>This is a really long line that I want to wrap around.</html>");
I recommend creating your own custom component that emulates the JLabel style while wrapping:
import javax.swing.JTextArea;
public class TextNote extends JTextArea {
public TextNote(String text) {
super(text);
setBackground(null);
setEditable(false);
setBorder(null);
setLineWrap(true);
setWrapStyleWord(true);
setFocusable(false);
}
}
Then you just have to call:
new TextNote("Here is multiline content.");
Make sure that you set the amount of rows (textNote.setRows(2)) if you want to pack() to calculate the height of the parent component correctly.
I suggest to use a JTextArea instead of a JLabel
and on your JTextArea you can use the method .setWrapStyleWord(true) to change line at the end of a word.
It is possible to use (basic) CSS in the HTML.
MultiLine Label with auto adjust height.
Wrap text in Label
private void wrapLabelText(JLabel label, String text) {
FontMetrics fm = label.getFontMetrics(label.getFont());
PlainDocument doc = new PlainDocument();
Segment segment = new Segment();
try {
doc.insertString(0, text, null);
} catch (BadLocationException e) {
}
StringBuffer sb = new StringBuffer("<html>");
int noOfLine = 0;
for (int i = 0; i < text.length();) {
try {
doc.getText(i, text.length() - i, segment);
} catch (BadLocationException e) {
throw new Error("Can't get line text");
}
int breakpoint = Utilities.getBreakLocation(segment, fm, 0, this.width - pointerSignWidth - insets.left - insets.right, null, 0);
sb.append(text.substring(i, i + breakpoint));
sb.append("<br/>");
i += breakpoint;
noOfLine++;
}
sb.append("</html>");
label.setText(sb.toString());
labelHeight = noOfLine * fm.getHeight();
setSize();
}
Thanks,
Jignesh Gothadiya

Categories