let me if have you anyone answer, this ans. basically required like as google search engine , when we press any key then it would be display suggestion related pressed key.
regard
Satish Dhiman
From my comment/previous code see this update:
Using JTextField with AutoSuggestor:
Using JTextArea (or any other JTextComponent besides JTextField will result in Pop up window being shown under caret) with AutoSuggestor:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
/**
* #author David
*/
public class Test {
public Test() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JTextField f = new JTextField(10);
JTextArea f = new JTextArea(10, 10);
//JEditorPane f = new JEditorPane();
//create words for dictionary could also use null as parameter for AutoSuggestor(..,..,null,..,..,..,..) and than call AutoSuggestor#setDictionary after AutoSuggestr insatnce has been created
ArrayList<String> words = new ArrayList<>();
words.add("hello");
words.add("heritage");
words.add("happiness");
words.add("goodbye");
words.add("cruel");
words.add("car");
words.add("war");
words.add("will");
words.add("world");
words.add("wall");
AutoSuggestor autoSuggestor = new AutoSuggestor(f, frame, words, Color.WHITE.brighter(), Color.BLUE, Color.RED, 0.75f) {
#Override
boolean wordTyped(String typedWord) {
System.out.println(typedWord);
return super.wordTyped(typedWord);//checks for a match in dictionary and returns true or false if found or not
}
};
JPanel p = new JPanel();
p.add(f);
frame.add(p);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
class AutoSuggestor {
private final JTextComponent textComp;
private final Window container;
private JPanel suggestionsPanel;
private JWindow autoSuggestionPopUpWindow;
private String typedWord;
private final ArrayList<String> dictionary = new ArrayList<>();
private int currentIndexOfSpace, tW, tH;
private DocumentListener documentListener = new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
#Override
public void removeUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
#Override
public void changedUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
};
private final Color suggestionsTextColor;
private final Color suggestionFocusedColor;
public AutoSuggestor(JTextComponent textComp, Window mainWindow, ArrayList<String> words, Color popUpBackground, Color textColor, Color suggestionFocusedColor, float opacity) {
this.textComp = textComp;
this.suggestionsTextColor = textColor;
this.container = mainWindow;
this.suggestionFocusedColor = suggestionFocusedColor;
this.textComp.getDocument().addDocumentListener(documentListener);
setDictionary(words);
typedWord = "";
currentIndexOfSpace = 0;
tW = 0;
tH = 0;
autoSuggestionPopUpWindow = new JWindow(mainWindow);
autoSuggestionPopUpWindow.setOpacity(opacity);
suggestionsPanel = new JPanel();
suggestionsPanel.setLayout(new GridLayout(0, 1));
suggestionsPanel.setBackground(popUpBackground);
addKeyBindingToRequestFocusInPopUpWindow();
}
private void addKeyBindingToRequestFocusInPopUpWindow() {
textComp.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
textComp.getActionMap().put("Down released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow
for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true);
autoSuggestionPopUpWindow.toFront();
autoSuggestionPopUpWindow.requestFocusInWindow();
suggestionsPanel.requestFocusInWindow();
suggestionsPanel.getComponent(i).requestFocusInWindow();
break;
}
}
}
});
suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
suggestionsPanel.getActionMap().put("Down released", new AbstractAction() {
int lastFocusableIndex = 0;
#Override
public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :))
ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels();
int max = sls.size();
if (max > 1) {//more than 1 suggestion
for (int i = 0; i < max; i++) {
SuggestionLabel sl = sls.get(i);
if (sl.isFocused()) {
if (lastFocusableIndex == max - 1) {
lastFocusableIndex = 0;
sl.setFocused(false);
autoSuggestionPopUpWindow.setVisible(false);
setFocusToTextField();
checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
} else {
sl.setFocused(false);
lastFocusableIndex = i;
}
} else if (lastFocusableIndex <= i) {
if (i < max) {
sl.setFocused(true);
autoSuggestionPopUpWindow.toFront();
autoSuggestionPopUpWindow.requestFocusInWindow();
suggestionsPanel.requestFocusInWindow();
suggestionsPanel.getComponent(i).requestFocusInWindow();
lastFocusableIndex = i;
break;
}
}
}
} else {//only a single suggestion was given
autoSuggestionPopUpWindow.setVisible(false);
setFocusToTextField();
checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
}
}
});
}
private void setFocusToTextField() {
container.toFront();
container.requestFocusInWindow();
textComp.requestFocusInWindow();
}
public ArrayList<SuggestionLabel> getAddedSuggestionLabels() {
ArrayList<SuggestionLabel> sls = new ArrayList<>();
for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
SuggestionLabel sl = (SuggestionLabel) suggestionsPanel.getComponent(i);
sls.add(sl);
}
}
return sls;
}
private void checkForAndShowSuggestions() {
typedWord = getCurrentlyTypedWord();
suggestionsPanel.removeAll();//remove previos words/jlabels that were added
//used to calcualte size of JWindow as new Jlabels are added
tW = 0;
tH = 0;
boolean added = wordTyped(typedWord);
if (!added) {
if (autoSuggestionPopUpWindow.isVisible()) {
autoSuggestionPopUpWindow.setVisible(false);
}
} else {
showPopUpWindow();
setFocusToTextField();
}
}
protected void addWordToSuggestions(String word) {
SuggestionLabel suggestionLabel = new SuggestionLabel(word, suggestionFocusedColor, suggestionsTextColor, this);
calculatePopUpWindowSize(suggestionLabel);
suggestionsPanel.add(suggestionLabel);
}
public String getCurrentlyTypedWord() {//get newest word after last white spaceif any or the first word if no white spaces
String text = textComp.getText();
String wordBeingTyped = "";
text = text.replaceAll("(\\r|\\n)", " ");
if (text.contains(" ")) {
int tmp = text.lastIndexOf(" ");
if (tmp >= currentIndexOfSpace) {
currentIndexOfSpace = tmp;
wordBeingTyped = text.substring(text.lastIndexOf(" "));
}
} else {
wordBeingTyped = text;
}
return wordBeingTyped.trim();
}
private void calculatePopUpWindowSize(JLabel label) {
//so we can size the JWindow correctly
if (tW < label.getPreferredSize().width) {
tW = label.getPreferredSize().width;
}
tH += label.getPreferredSize().height;
}
private void showPopUpWindow() {
autoSuggestionPopUpWindow.getContentPane().add(suggestionsPanel);
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.setSize(tW, tH);
autoSuggestionPopUpWindow.setVisible(true);
int windowX = 0;
int windowY = 0;
if (textComp instanceof JTextField) {//calculate x and y for JWindow at bottom of JTextField
windowX = container.getX() + textComp.getX() + 5;
if (suggestionsPanel.getHeight() > autoSuggestionPopUpWindow.getMinimumSize().height) {
windowY = container.getY() + textComp.getY() + textComp.getHeight() + autoSuggestionPopUpWindow.getMinimumSize().height;
} else {
windowY = container.getY() + textComp.getY() + textComp.getHeight() + autoSuggestionPopUpWindow.getHeight();
}
} else {//calculate x and y for JWindow on any JTextComponent using the carets position
Rectangle rect = null;
try {
rect = textComp.getUI().modelToView(textComp, textComp.getCaret().getDot());//get carets position
} catch (BadLocationException ex) {
ex.printStackTrace();
}
windowX = (int) (rect.getX() + 15);
windowY = (int) (rect.getY() + (rect.getHeight() * 3));
}
//show the pop up
autoSuggestionPopUpWindow.setLocation(windowX, windowY);
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.revalidate();
autoSuggestionPopUpWindow.repaint();
}
public void setDictionary(ArrayList<String> words) {
dictionary.clear();
if (words == null) {
return;//so we can call constructor with null value for dictionary without exception thrown
}
for (String word : words) {
dictionary.add(word);
}
}
public JWindow getAutoSuggestionPopUpWindow() {
return autoSuggestionPopUpWindow;
}
public Window getContainer() {
return container;
}
public JTextComponent getTextField() {
return textComp;
}
public void addToDictionary(String word) {
dictionary.add(word);
}
boolean wordTyped(String typedWord) {
if (typedWord.isEmpty()) {
return false;
}
//System.out.println("Typed word: " + typedWord);
boolean suggestionAdded = false;
for (String word : dictionary) {//get words in the dictionary which we added
boolean fullymatches = true;
for (int i = 0; i < typedWord.length(); i++) {//each string in the word
if (!typedWord.toLowerCase().startsWith(String.valueOf(word.toLowerCase().charAt(i)), i)) {//check for match
fullymatches = false;
break;
}
}
if (fullymatches) {
addWordToSuggestions(word);
suggestionAdded = true;
}
}
return suggestionAdded;
}
}
class SuggestionLabel extends JLabel {
private boolean focused = false;
private final JWindow autoSuggestionsPopUpWindow;
private final JTextComponent textComponent;
private final AutoSuggestor autoSuggestor;
private Color suggestionsTextColor, suggestionBorderColor;
public SuggestionLabel(String string, final Color borderColor, Color suggestionsTextColor, AutoSuggestor autoSuggestor) {
super(string);
this.suggestionsTextColor = suggestionsTextColor;
this.autoSuggestor = autoSuggestor;
this.textComponent = autoSuggestor.getTextField();
this.suggestionBorderColor = borderColor;
this.autoSuggestionsPopUpWindow = autoSuggestor.getAutoSuggestionPopUpWindow();
initComponent();
}
private void initComponent() {
setFocusable(true);
setForeground(suggestionsTextColor);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
replaceWithSuggestedText();
autoSuggestionsPopUpWindow.setVisible(false);
}
});
getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "Enter released");
getActionMap().put("Enter released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
replaceWithSuggestedText();
autoSuggestionsPopUpWindow.setVisible(false);
}
});
}
public void setFocused(boolean focused) {
if (focused) {
setBorder(new LineBorder(suggestionBorderColor));
} else {
setBorder(null);
}
repaint();
this.focused = focused;
}
public boolean isFocused() {
return focused;
}
private void replaceWithSuggestedText() {
String suggestedWord = getText();
String text = textComponent.getText();
String typedWord = autoSuggestor.getCurrentlyTypedWord();
String t = text.substring(0, text.lastIndexOf(typedWord));
String tmp = t + text.substring(text.lastIndexOf(typedWord)).replace(typedWord, suggestedWord);
textComponent.setText(tmp + " ");
}
}
As you can see I changed the code by making its constructor accept a JTextComponent rather than a JTextField or JTextArea etc.
The problem we are left with is we have to show the pop up JWindow at a different position depending on the JTextComponent passed i.e a JTextField will have autosuggest window pop up at the bottom while JTextArea/JEditorPane etc would have the JWindow pop up under the caret/word.
Have a look at this specific method showPopUpWindow() in AutoSuggestor class:
private void showPopUpWindow() {
autoSuggestionPopUpWindow.getContentPane().add(suggestionsPanel);
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.setSize(tW, tH);
autoSuggestionPopUpWindow.setVisible(true);
int windowX = 0;
int windowY = 0;
if (textComp instanceof JTextField) {//calculate x and y for JWindow at bottom of JTextField
windowX = container.getX() + textComp.getX() + 5;
if (suggestionsPanel.getHeight() > autoSuggestionPopUpWindow.getMinimumSize().height) {
windowY = container.getY() + textComp.getY() + textComp.getHeight() + autoSuggestionPopUpWindow.getMinimumSize().height;
} else {
windowY = container.getY() + textComp.getY() + textComp.getHeight() + autoSuggestionPopUpWindow.getHeight();
}
} else {//calculate x and y for JWindow on any JTextComponent using the carets position
Rectangle rect = null;
try {
rect = textComp.getUI().modelToView(textComp, textComp.getCaret().getDot());//get carets position
} catch (BadLocationException ex) {
ex.printStackTrace();
}
windowX = (int) (rect.getX() + 15);
windowY = (int) (rect.getY() + (rect.getHeight() * 3));
}
//show the pop up
autoSuggestionPopUpWindow.setLocation(windowX, windowY);
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.revalidate();
autoSuggestionPopUpWindow.repaint();
}
As you can see we check to see what instance the JTextComponent is and if its not a JTextField simply get the caret position (via the Rectangle of the caret) of the JTextComponent and position JWindow pop up from there (underneath the caret in my case).
I can propose my own implementation. It is based on JList shown in JWindow.
As I wanted to use this code for a combo box, I've disabled UP and DOWN keys with keyEvent.consume() call.
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class GAutoCompletionDecorator {
private final JTextComponent textComponent;
private final JWindow suggestionsPopup;
private final JList completionList;
private final DefaultListModel completionListModel;
public static void decorate(JComboBox comboBox, JFrame parent) {
comboBox.setEditable(true);
final JTextComponent textComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
decorate(textComponent, parent);
}
private static void decorate(JTextComponent textComponent, JFrame parent) {
final GAutoCompletionDecorator autoCompletionDecorator = new GAutoCompletionDecorator(textComponent, parent);
autoCompletionDecorator.decorate();
}
private GAutoCompletionDecorator(final JTextComponent textComponent, JFrame parent) {
this.textComponent = textComponent;
this.suggestionsPopup = new JWindow(parent);
this.completionListModel = new DefaultListModel();
this.completionList = new JList();
this.completionList.setModel(completionListModel);
this.suggestionsPopup.getContentPane().add(this.completionList);
}
private void decorate() {
textComponent.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent documentEvent) {
updateSuggestions();
}
public void removeUpdate(DocumentEvent documentEvent) {
updateSuggestions();
}
public void changedUpdate(DocumentEvent documentEvent) {
updateSuggestions();
}
});
this.textComponent.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent keyEvent) {
if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN || keyEvent.getKeyCode() == KeyEvent.VK_UP) {
updateSuggestions();
completionList.requestFocus();
completionList.dispatchEvent(keyEvent);
keyEvent.consume();
}
}
public void keyReleased(KeyEvent keyEvent) {
if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN || keyEvent.getKeyCode() == KeyEvent.VK_UP) {
keyEvent.consume();
}
}
});
this.completionList.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent keyEvent) {
if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) {
textComponent.requestFocus();
hideSuggestionsPopup();
} else if (keyEvent.getKeyCode() == KeyEvent.VK_UP) {
if (completionList.getSelectedIndex() == 0) {
completionList.setSelectedIndex(completionListModel.size() - 1);
keyEvent.consume();
}
} else if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
if (completionList.getSelectedIndex() == completionListModel.size() - 1) {
completionList.setSelectedIndex(0);
keyEvent.consume();
}
} else if (keyEvent.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
textComponent.requestFocus();
hideSuggestionsPopup();
textComponent.dispatchEvent(keyEvent);
} else if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) {
textComponent.requestFocus();
hideSuggestionsPopup();
final String selectedSuggestion = (String) completionList.getSelectedValue();
if (selectedSuggestion != null) {
try {
final int caretPosition = textComponent.getCaretPosition();
textComponent.getDocument().insertString(caretPosition, getCompletionString(selectedSuggestion, textComponent.getText(), caretPosition), null);
} catch (BadLocationException e) {
//ignore
}
}
}
}
});
}
private String getCompletionString(String selectedSuggestion, String text, int caretPosition) {
//we may insert selectedSuggestion fully of some part of it
return selectedSuggestion;
}
private void updateSuggestions() {
final String text = textComponent.getText();
final int caretPosition = textComponent.getCaretPosition();
final List<String> suggestions = getSuggestions(text, caretPosition);
if (suggestions == null || suggestions.size() == 0) {
//hide suggestions window
hideSuggestionsPopup();
} else {
//show suggestions window
showSuggestionsPopup(suggestions);
}
}
private void hideSuggestionsPopup() {
suggestionsPopup.setVisible(false);
}
private void showSuggestionsPopup(List<String> suggestions) {
completionListModel.clear();
for (String suggestion : suggestions) {
completionListModel.addElement(suggestion);
}
final Point textComponentLocation = new Point(textComponent.getLocation());
SwingUtilities.convertPointToScreen(textComponentLocation, textComponent);
Point caretLocation = textComponent.getCaret().getMagicCaretPosition();
if (caretLocation != null) {
caretLocation = new Point(caretLocation);
SwingUtilities.convertPointToScreen(caretLocation, textComponent);
}
suggestionsPopup.pack();
suggestionsPopup.setLocation(caretLocation == null ? textComponentLocation.x : caretLocation.x,
textComponentLocation.y + textComponent.getHeight());
suggestionsPopup.setVisible(true);
}
private List<String> getSuggestions(String text, int caretPosition) {
final List<String> words = new ArrayList<String>();
words.add("suggestion 1");
words.add("suggestion 2");
words.add("suggestion 3");
words.add("suggestion 4");
words.add("suggestion 5");
//make suggestions funny
return text.length() < words.size() ? words.subList(0, words.size() - text.length()) : Collections.<String>emptyList();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JComboBox comboBox = new JComboBox(new String[] {"Choice1", "Choice2"});
comboBox.setEditable(true);
GAutoCompletionDecorator.decorate(comboBox, frame);
frame.add(comboBox);
frame.pack();
frame.setVisible(true);
}
});
}
}
Related
I'm trying to write a kanban board. But if there are two and more stickers in one column, often the JToolBar with buttons will be shown only if you click on a sticker in this column for the firs time.
I thought that there were some problems with coordinates, but I didn't found it. The StickerListener responds th event, even prints "условие работает" if coordinates are correct, but the JToolBar remainds invisible.
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String[] args)
{
Window window = new Window();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Window extends JFrame {
public JButton Edit;
public JButton Read;
public JButton Delete;
private Window window;
private JToolBar jtb;
public boolean stickerToolBarActivated;
public Window() {
window= this;
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
Desk d = new Desk();
createMenu(d);
add(d);
setDefaultSizeToProgressTypesColumns(d, this);
d.setBackground(new Color(255, 255, 255));
StickerListener sl = new StickerListener(d, this);
this.addMouseMotionListener(sl);
this.addMouseListener(sl);
this.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
setDefaultSizeToProgressTypesColumns(d,window);
}
#Override
public void componentMoved(ComponentEvent e) {}
#Override
public void componentShown(ComponentEvent e) {}
#Override
public void componentHidden(ComponentEvent e) {}
});
jtb = new JToolBar();
Edit = new JButton("Редактровать");
jtb.add(Edit);
Delete = new JButton("Удалить");
jtb.add(Delete);
Read = new JButton("Просмотреть");
jtb.add(Read);
add(jtb, BorderLayout.NORTH);
jtb.setVisible(false);
stickerToolBarActivated=false;
setVisible(true);
}
private void createMenu(Desk d)
{
JMenuBar menuBar = new JMenuBar();
JMenu DeskFile = new JMenu("Файл");
JMenuItem SaveDesk = new JMenuItem("Сохранить доску");
DeskFile.add(SaveDesk);
menuBar.add(DeskFile);
JMenu StickerOptions = new JMenu("Стикер");
JMenuItem NewSticker = new JMenuItem("Добавить стикер");
NewSticker.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
d.ProgressTypes.get(0).addSticker();
setDefaultSizeToProgressTypesColumns(d, window);
d.repaint();
}
});
StickerOptions.add(NewSticker);
menuBar.add(StickerOptions);
add(menuBar, BorderLayout.NORTH);
setJMenuBar(menuBar);
}
public JToolBar getStickerToolbar() {
return jtb;
}
public static void setDefaultSizeToProgressTypesColumns(Desk d, Window window)
{
int x=0;
int y=0;
int WindowWidth = window.getWidth();
int WindowHeight = window.getHeight();
int ptCount = d.ProgressTypes.size();
for(ProgressType pt: d.ProgressTypes)
{
pt.x=x;
pt.y=y;
pt.width= WindowWidth/ptCount;
pt.height = WindowHeight;
x+=pt.width;
for(int s=0; s<pt.stickers.size(); ++s) {
pt.stickers.get(s).setWidth(pt.width);
pt.stickers.get(s).setHeight(pt.width);
pt.stickers.get(s).y=pt.height/20+pt.width*s;
pt.stickers.get(s).x=pt.x;
}
}
}
public JButton getEdit() {
return Edit;
}
}
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class Desk extends JPanel {
public ArrayList<ProgressType> ProgressTypes;
public int width;
public Desk()
{
ProgressTypes = new ArrayList<ProgressType>();
ProgressTypes.add(new ProgressType("Идеи"));
ProgressTypes.add(new ProgressType("Сделать"));
ProgressTypes.add(new ProgressType("В процессе"));
ProgressTypes.add(new ProgressType("Тестируется"));
ProgressTypes.add(new ProgressType("Готово"));
}
#Override
public void paint(Graphics g) {
super.paint(g);
for(ProgressType pt: ProgressTypes) {
pt.paint(g);
}
for(ProgressType pt: ProgressTypes)
for(Sticker s : pt.stickers)
s.paint(g);
}
}
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ProgressType extends JPanel {
public ArrayList<Sticker> stickers;
public String name;
public int x, y, width, height;
public ProgressType(String n)
{
this.name = n;
stickers = new ArrayList<>();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
final BasicStroke borderLine = new BasicStroke(4.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 5.0f);
g2d.setStroke(borderLine);
g2d.setColor(Color.black);
g2d.drawLine(x, y, x+width, y);
g2d.drawLine(x, y, x, y+height);
g2d.drawLine(x, y+height/20, x+width, y+height/20); //height/20 это высота шапки таблицы
g2d.drawLine(x+width, y, x+width, y+height);
}
public int findSticker(String search) {
for(int i=0; i<stickers.size(); ++i)
{
if(stickers.get(i).title.matches(search))
return i;
}
return -1;
}
public void addSticker()
{
StickerBuilder sb = new StickerBuilder();
Sticker s = sb.getSticker();
s.y=(height/20)+(width*stickers.size())+5;
stickers.add(s);
repaint();
}
public void addSticker(Sticker s)
{
for(int i=0; i<stickers.size(); ++i)
{
stickers.get(i).y=s.y=(height/20)+(width*(i+1))+5*(i+1);
}
s.y=(height/20);
stickers.add(s);
}
}
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
public class Sticker extends JPanel {
public String text;
private String Progress;
public String title;
private BufferedImage img;
public int x;
public int y;
public int width;
public int height;
public Sticker ( String text, String Progress,String title, int x, int y)
{
this.text=text;
this.Progress=Progress;
this.title = title;
this.x=x;
this.y=y;
this.width = -1;
this.height = -1;
try {
URL resource = Sticker.class.getResource("\\transparentSticker.png");
img = null;
this.img = ImageIO.read(Paths.get(resource.toURI()).toFile());
System.out.println("c");
} catch (IOException | URISyntaxException e) {
System.out.println("caught");
}
}
public void setText(String text) {
this.text = text;
}
public void setProgress(String progress) {
Progress = progress;
}
public void setTitle(String title) {
this.title = title;
}
public void setWidth(int width){
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public Sticker clone()
{
Sticker s= new Sticker(text, Progress, title, x, y);
s.setHeight(width);
s.setWidth(width);
return s;
}
#Override
public void paint(Graphics g) {
super.paint(g);
System.out.print("p");
g.drawImage(img, x, y, width-4, height, null);
String NormStr;
if(title!=null) {
NormStr = NormalizeLabel(title, g);
g.drawString(NormStr, x, y + width / 5);
}
if(text!=null) {
NormStr = NormalizeLabel(text, g);
FontMetrics fm = g.getFontMetrics(g.getFont());
int hgt = fm.getHeight();
String [] n=NormStr.split("\n");
for(int i= 0; i<n.length; ++i) {
g.drawString(n[i], x, y + width / 5 + hgt * 13 / 10 * (i + 1));
if(width / 5 + hgt * 13 / 10 * (i + 1)>=width*0.75)
{
g.drawString("...", x, y + width / 5 + hgt * 13 / 10 * (i + 1));
break;
}
}
}
}
private String NormalizeLabel(String s, Graphics g)
{
String NormalizedString = "";
String buf="";
FontMetrics fm = g.getFontMetrics(g.getFont());
int hgt= fm.getHeight();
int strw=0;
for(int i=0; i<s.length(); ++i)
{
buf+=s.charAt(i);
strw=fm.stringWidth(buf);
if(strw>=width*0.75)
{
NormalizedString+=buf;
NormalizedString+="\n";
buf="";
}
}
NormalizedString+=buf;
return NormalizedString;
}
}
import java.util.ArrayList;
public interface Builder {
void setText(String text);
void setProgress(String Progress);
void setTitle(String title);
Sticker getSticker();
}
import java.util.ArrayList;
public class StickerBuilder implements Builder{
public StickerBuilder() {
}
private String text;
private String Progress;
private String title;
public void setText(String text) {
this.text = text;
}
public void setProgress(String progress) {
Progress = progress;
}
public void setTitle(String title) {
this.title = title;
}
public Sticker getSticker()
{
return new Sticker(text, Progress, title, 0, 0);//возможно, стоит добавить функцию для х и у
}
}
import java.util.ArrayList;
import javax.swing.*;
import java.awt.*;
public class StickerChanger implements Builder {
private Sticker sticker;
public StickerChanger(Sticker sticker) {
this.sticker = sticker;
}
#Override
public void setText(String text) {
this.sticker.setText(text);
}
#Override
public void setProgress(String Progress) {
this.sticker.setProgress(Progress);
}
#Override
public void setTitle(String title) {
this.sticker.setTitle(title);
}
#Override
public Sticker getSticker() {
return null;
}
}
import javax.swing.*;
import java.awt.event.*;
import java.util.ArrayList;
public class StickerListener implements MouseMotionListener, MouseListener {
private ArrayList<ProgressType> PTs;
private boolean StickerIsBeingDragged;
private int DistanceToTheEndX;
private int DistanceToTheEndY;
private Sticker CurrentSticker;
private Desk d;
private Window window;
private boolean sd2;
private final int Y_DELTA=50;
private ActionListener del;
private ActionListener edit;
private ActionListener rd;
private StickerEditorWindow sew;
public StickerListener(Desk d, Window w)
{
this.d = d;
this.PTs=d.ProgressTypes;
this.DistanceToTheEndX=this.DistanceToTheEndY=0;
this.StickerIsBeingDragged = this.sd2=false;
this.window =w;
}
#Override
public void mouseDragged(MouseEvent e) {
if (StickerIsBeingDragged)
{
sd2=true;
CurrentSticker.x=e.getX()-DistanceToTheEndX;
CurrentSticker.y=e.getY()-DistanceToTheEndY;
System.out.println(CurrentSticker.x+" "+CurrentSticker.y+" "+e.getX()+" "+ e.getY()+" "+"dragged");
d.repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
boolean f = true;
if(e.getButton() == MouseEvent.BUTTON1)
for (ProgressType pt : PTs) {
for (Sticker s : pt.stickers) {
System.out.println((e.getX() >= s.x) + " " + (e.getX() <= (s.x + s.width))+ " " +
(e.getY()-Y_DELTA >= s.y ) + " " + (e.getY()-Y_DELTA <= (s.y + s.width)));
System.out.println(e.getX() + " "+ e.getY()+ " " + s.x+ " "+ s.y);
if (e.getX() >= s.x && e.getX() <= (s.x + s.width) &&
e.getY()-Y_DELTA >= s.y && e.getY()-Y_DELTA <= (s.y + s.width)) {
CurrentSticker = s;
f=false;
JToolBar jtb = window.getStickerToolbar();
jtb.setVisible(true);
System.out.println("условие работает");
window.stickerToolBarActivated = true;
setListeners(s, pt, jtb);
f = false;
//Sticker buf = (Sticker) CurrentSticker.clone();
//pt.addSticker(buf);
d.repaint();
} else {
window.getStickerToolbar().setVisible(false);
sew = null;
window.stickerToolBarActivated = false;
if(rd!=null)
{
window.Read.removeActionListener(rd);
rd = null;
}
if(del!=null)
{
window.Delete.removeActionListener(del);
del = null;
}
if(edit!=null)
{
window.Edit.removeActionListener(edit);
edit = null;
}
}
}
}
System.out.println(e.getX()+" "+ e.getY()+" "+"cliicked");
}
private void setListeners(Sticker s, ProgressType pt, JToolBar jtb) {
del = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int iRes = JOptionPane.showConfirmDialog(window, "Удалить этот стикер?", "",
JOptionPane.YES_NO_OPTION);
if (iRes == JOptionPane.YES_NO_OPTION) {
pt.stickers.remove(s);
jtb.setVisible(false);
d.repaint();
}
}
};
edit = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (sew == null) {
createStickerEditorWindow(s);
}
}
};
rd = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
StickerReadingWindow srw = new StickerReadingWindow(s);
}
};
window.Delete.addActionListener(del);
window.Edit.addActionListener(edit);
window.Read.addActionListener(rd);
}
#Override
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1)
for(ProgressType pt: PTs) {
for (Sticker s : pt.stickers) {
if (e.getX() >= s.x && e.getX() <= (s.x + s.width) &&
e.getY()-Y_DELTA >= s.y && e.getY()-Y_DELTA <= (s.y + s.width)) {
DistanceToTheEndX = e.getX()-s.x;
DistanceToTheEndY = e.getY()-s.y;
StickerIsBeingDragged = true;
CurrentSticker = s;
System.out.println(s.x+" "+s.y+" "+e.getX()+" "+ e.getY()+" "+"pressed");
}
}
}
}
private void createStickerEditorWindow(Sticker s)
{
DefaultListModel listModel = new DefaultListModel();
for (ProgressType pt: PTs)
listModel.addElement(pt.name);
sew = new StickerEditorWindow(s, listModel);
sew.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
sew=null;
d.repaint();
}
});
}
#Override
public void mouseReleased(MouseEvent e) {
if(StickerIsBeingDragged) {
if(sd2) {
System.out.println(CurrentSticker.x + " " + CurrentSticker.y + " " + e.getX() + " " + e.getY() + " " + "released");
StickerIsBeingDragged = false;
d.repaint();
if (CurrentSticker.x < 0)
CurrentSticker.x = 0;
else if (CurrentSticker.x > window.getWidth())
CurrentSticker.x = window.getWidth() - 15;
for (ProgressType pt : PTs) {
if (CurrentSticker.x >= pt.x && CurrentSticker.x < pt.x + pt.width && CurrentSticker.x >= 0) {
CurrentSticker.x = pt.x;
Sticker buf = (Sticker) CurrentSticker.clone();
pt.addSticker(buf);
}
if (pt.stickers.indexOf(CurrentSticker) != -1) {
pt.stickers.remove(CurrentSticker);
}
}
sd2=false;
d.repaint();
}
}
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
public class StickerEditorWindow extends JFrame {
private Sticker sticker;
private JTextField title;
private JTextArea text;
private JList ProgressTypes;
private JButton Save;
private JButton DelayTitleChanges;
private JButton DelayTextChanges;
private JButton DelayProgressTypeChanges;
private DefaultListModel listModel;
public StickerEditorWindow(Sticker s, DefaultListModel lm) {
this.sticker = s;
setSize(600,300);
setTitle("Редактировать стикер");
setAlwaysOnTop(true);
// setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(
0, 0,
1, 1,
4, 0,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets(5, 5, 5, 5),
0, 0
);
title = new JTextField("Тема");
text = new JTextArea("Введите текст");
this.listModel = lm;
ProgressTypes = new JList(listModel);
this.add(title, gbc);
++gbc.gridy;
gbc.weighty=4;
this.add(text, gbc);
this.add(new JScrollPane(text), gbc);
gbc.weighty=0;
++gbc.gridy;
this.add(ProgressTypes, gbc);
ProgressTypes.setFocusable(false);
this.add(new JScrollPane(ProgressTypes), gbc);
ProgressTypes.setVisible(true);
Save = new JButton("Cохранить");
DelayTitleChanges = new JButton("Отменить изм. темы");
DelayTextChanges = new JButton("Отменить изм. текста");
DelayProgressTypeChanges = new JButton("Отменить изм. колонки прогресса");
gbc.gridx=1;
gbc.weightx=1;
gbc.gridy = 3;
this.add(Save, gbc);
gbc.gridy = 0;
this.add(DelayTitleChanges, gbc);
gbc.gridy = 1;
gbc.weighty=4;
this.add(DelayTextChanges, gbc);
gbc.gridy = 2;
this.add(DelayProgressTypeChanges, gbc);
if(sticker.text!=null) {
text.setText(sticker.text);
}
if(sticker.title!=null)
title.setText(sticker.title);
setListeners();
setVisible(true);
}
private void setListeners()
{
StickerEditorWindow w = this;
this.Save.addActionListener(new StickerChangeListener(w, this.Save));
this.DelayProgressTypeChanges.addActionListener(new StickerChangeListener(w, this.DelayProgressTypeChanges));
this.DelayTitleChanges.addActionListener(new StickerChangeListener(w, this.DelayTitleChanges));
this.DelayTextChanges.addActionListener(new StickerChangeListener(w, this.DelayTextChanges));
}
public void SaveStickerChanges()
{
sticker.title=title.getText();
sticker.text = text.getText();
}
public void CancelTitleChanges()
{
title.setText(sticker.title);
}
public void CancelTextChanges()
{
text.setText(sticker.text);
}
}
import javax.swing.*;
import javax.swing.plaf.basic.BasicOptionPaneUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class StickerChangeListener implements ActionListener {
private StickerEditorWindow sew;
private JButton sender;
public StickerChangeListener(StickerEditorWindow sew, JButton sender) {
this.sew = sew;
this.sender = sender;
}
#Override
public void actionPerformed(ActionEvent e) {
if(sender.getText().equals("Cохранить")){
sew.SaveStickerChanges();
}
if(sender.getText().equals("Отменить изм. темы")){
sew.CancelTitleChanges();
}
if(sender.getText().equals("Отменить изм. текста")){
sew.CancelTextChanges();
}
if(sender.getText().equals("Отменить изм. колонки прогресса")){}
}
}
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
public class StickerReadingWindow extends JFrame{
private Sticker sticker;
private int width;
private int height;
ReadingCrutch rc;
public StickerReadingWindow(Sticker s) throws HeadlessException {
this.sticker = s;
width=height=500;
String winHeader = "";
if(sticker.title!=null)
winHeader+="Тема: "+sticker.title+ " ";
setTitle(winHeader);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel jp = new JPanel();
add(jp);
Graphics g =jp.getGraphics();
setSize(width,height);
setTitle("Редактировать стикер");
setAlwaysOnTop(true);
BufferedImage img = null;
try {
URL resource = Sticker.class.getResource("\\transparentSticker.png");
img = ImageIO.read(Paths.get(resource.toURI()).toFile());
System.out.println("c");
} catch (IOException | URISyntaxException e) {
System.out.println("caught");
}
if(img!=null)
rc = new ReadingCrutch(img, sticker.text, width);
add(rc);
setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class ReadingCrutch extends JPanel {
private BufferedImage img;
private String str;
private int width;
public ReadingCrutch(BufferedImage img, String str, int w) {
this.img = img;
this.str = str;
this.width =w;
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(img, 0, 0, 450, 450, null);
g.setColor(Color.black);
String txt = str;
String [] s=txt.split(" ");
String buf= "";
String NormalizedString="";
FontMetrics fm = g.getFontMetrics(g.getFont());
int hgt= fm.getHeight();
int strw=0;
for(int i=0; i<s.length; ++i)
{
buf+=s[i]+" ";
strw=fm.stringWidth(buf);
if(strw>=width*0.75)
{
NormalizedString+=buf;
NormalizedString+="\n";
buf="";
}
}
NormalizedString+=buf;
g.setColor(Color.black);
String[] forWrite= NormalizedString.split("\n");
for(int i=0; i<forWrite.length; ++i)
{
g.drawString(forWrite[i]+" ", 0, 0 + width / 5 + hgt * 13 / 10 * (i + 1));
}
}
}
The problem is in the control flow of the StickerListener.mouseClicked(): you search the stickers to find the one that has been clicked.
Due to the if / else you reset the toolbar for every sticker that has not been clicked, meaning that your code only works if you clicked on the last sticker (in order of iteration).
Your code will work if you move the code from the else part before the loop (so that it executes only once):
#Override
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
window.getStickerToolbar().setVisible(false);
sew = null;
window.stickerToolBarActivated = false;
if (rd != null) {
window.Read.removeActionListener(rd);
rd = null;
}
if (del != null) {
window.Delete.removeActionListener(del);
del = null;
}
if (edit != null) {
window.Edit.removeActionListener(edit);
edit = null;
}
for (ProgressType pt : PTs) {
for (Sticker s : pt.stickers) {
System.out.println((e.getX() >= s.x) + " " + (e.getX() <= (s.x + s.width)) + " " +
(e.getY() - Y_DELTA >= s.y) + " " + (e.getY() - Y_DELTA <= (s.y + s.width)));
System.out.println(e.getX() + " " + e.getY() + " " + s.x + " " + s.y);
if (e.getX() >= s.x && e.getX() <= (s.x + s.width) &&
e.getY() - Y_DELTA >= s.y && e.getY() - Y_DELTA <= (s.y + s.width)) {
CurrentSticker = s;
JToolBar jtb = window.getStickerToolbar();
jtb.setVisible(true);
System.out.println("условие работает");
window.stickerToolBarActivated = true;
setListeners(s, pt, jtb);
//Sticker buf = (Sticker) CurrentSticker.clone();
//pt.addSticker(buf);
d.repaint();
return;
}
}
}
}
System.out.println(e.getX()+" "+ e.getY()+" "+"cliicked");
}
I had an issue with a piece of code I was writing where I was adding JPanel's inside of others to form a layout. The issue is that after the window is displayed I needed to get the x and y coordinates of one of the text fields but whenever I try using the getX() and getY() methods they keep returning 0. I have verified that the getX() and getY() methods are being called after the window is initialized and displayed. How can I fix this and get the actual coordinates of the text field.
This is window code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
public class GraphicsPanel extends JFrame implements ActionListener, CaretListener{
JPanel buttonPanel = new JPanel();
JPanel mainPanel = new JPanel();
JPanel animationPanel = new JPanel();
JPanel bottomPanel = new JPanel();
JPanel text = new JPanel();
PokemonLearnsets info = new PokemonLearnsets();
HealthBar healthBar1 = new HealthBar();
HealthBar healthBar2 = new HealthBar();
JTextArea textArea = new JTextArea();
JTextField response = new JTextField();
int health1 = 100;
int total1 = 100;
int health2 = 100;
int total2 = 100;
int startOfRect = 1;
int p1MonNum = -1;
int waitTime = 20;
int p2MonNum = -1;
TextInterface theText;
Icon allIcons[][];
JLabel p1Gif;
JLabel p2Gif;
JPanel mainBuilderPanel = new JPanel();
JPanel builderPanel = new JPanel();
JPanel builderMessagePanel = new JPanel();
JPanel monPanels [] = new JPanel[6];
JPanel imagePanels[] = new JPanel[6];
JPanel namePanels[] = new JPanel[6];
JPanel movePanels[] = new JPanel[6];
JPanel allMoves[][] = new JPanel[6][4];
JTextField names[] = new JTextField[6];
JTextField moves[][] = new JTextField[6][4];
JButton validate = new JButton("Validate");
JLabel tempImages[] = new JLabel[6];
JLabel emptyLabels[] = new JLabel[6];
AutoSuggestor [] nameSuggestions = new AutoSuggestor[6];
AutoSuggestor [][] moveSuggestions = new AutoSuggestor[6][4];
public GraphicsPanel(String name){
super(name);
setupTeamBuilderPanel();
// setupBattlePanel();
}
private void setupTeamBuilderPanel() {
Container c = getContentPane();
mainBuilderPanel.setLayout(new BorderLayout());
mainBuilderPanel.setBorder(new LineBorder(Color.BLACK, 2));
builderPanel.setLayout(new GridLayout(1, 0));
builderPanel.setBorder(new LineBorder(Color.BLACK, 1));
builderMessagePanel.setBorder(new LineBorder(Color.BLACK, 2));
for (int i = 0; i < monPanels.length; i ++) {
monPanels[i] = new JPanel();
imagePanels[i] = new JPanel();
namePanels[i] = new JPanel();
movePanels[i] = new JPanel();
names[i] = new JTextField();
names[i].addCaretListener(this);
emptyLabels[i] = new JLabel();
tempImages[i] = emptyLabels[i];
monPanels[i].setBorder(new LineBorder(Color.BLACK, 3));
imagePanels[i].setBorder(new LineBorder(Color.BLACK, 3));
movePanels[i].setBorder(new LineBorder(Color.BLACK, 3));
monPanels[i].setLayout(new GridLayout(0 ,1));
namePanels[i].setLayout(new GridLayout(1, 0));
movePanels[i].setLayout(new GridLayout(0, 1));
imagePanels[i].setLayout(new BorderLayout());
namePanels[i].add(new JLabel(" Name:"));
namePanels[i].add(names[i]);
imagePanels[i].add(tempImages[i]);
imagePanels[i].add(namePanels[i], BorderLayout.SOUTH);
monPanels[i].add(imagePanels[i]);
for (int k = 0; k < moves[i].length; k ++) {
moves[i][k] = new JTextField();
allMoves[i][k] = new JPanel();
allMoves[i][k].setLayout(new GridLayout(0, 1));
allMoves[i][k].add(new JLabel(" Move " + Integer.toString(k + 1) + ":"));
allMoves[i][k].add(moves[i][k]);
allMoves[i][k].add(new JLabel());
allMoves[i][k].add(new JLabel());
movePanels[i].add(allMoves[i][k]);
}
monPanels[i].add(movePanels[i]);
builderPanel.add(monPanels[i]);
}
String welcomeMessage = "";
for (int i = 0; i < 5; i ++) {
welcomeMessage += " ";
}
welcomeMessage += "Welcome to the Teambuilder!";
setupSuggestions();
validate.addActionListener(this);
builderMessagePanel.add(new JLabel(welcomeMessage));
mainBuilderPanel.add(builderMessagePanel, BorderLayout.NORTH);
mainBuilderPanel.add(validate, BorderLayout.SOUTH);
mainBuilderPanel.add(builderPanel);
c.add(mainBuilderPanel);
}
private void setupBattlePanel() {
Container c = getContentPane();
mainPanel.setLayout(new GridLayout());
bottomPanel.setLayout(new GridLayout());
animationPanel.setBorder(new LineBorder(Color.BLACK, 3));
animationPanel.setLayout(new GridLayout(0, 2));
mainPanel.add(animationPanel);
buttonPanel.setBorder(new LineBorder(Color.BLACK, 3));
buttonPanel.setLayout(new FlowLayout(5));
buttonPanel.setBackground(Color.GREEN);
// buttonPanel.add(new JLabel(" "));
// buttonPanel.add(new JButton("Testing"));
// buttonPanel.add(new JButton("Testing"));
// buttonPanel.add(new JButton("Testing"));
// buttonPanel.add(new JButton("Testing"));
bottomPanel.add(buttonPanel);
text.setLayout(new GridLayout());
text.setBorder(new LineBorder(Color.BLACK, 3));
text.add(response);
bottomPanel.add(text);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setEditable(false);
textArea.setBackground(Color.LIGHT_GRAY);
JScrollPane textAreaPane = new JScrollPane(textArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
textAreaPane.setBorder(new LineBorder(Color.BLACK, 3));
mainPanel.add(textAreaPane);
c.add(mainPanel, BorderLayout.CENTER);
c.add(bottomPanel, BorderLayout.SOUTH);
}
private void setupSuggestions() {
ArrayList<String> allPossibleMoves = new ArrayList<String>();
Collections.addAll(allPossibleMoves, info.getAllMoves());
for (int i = 0; i < 6; i ++) {
for (int k = 0; k < 4; k ++) {
moveSuggestions[i][k] = new AutoSuggestor(moves[i][k], allPossibleMoves, Color.WHITE.brighter(), Color.BLACK, Color.BLACK, 0.75f);
moveSuggestions[i][k].setTextField(moves[i][k]);
}
}
}
public void writeToScreen(String writing) {
String current = textArea.getText();
textArea.setText(current + writing);
}
public void updateAll() {
mainPanel.updateUI();
bottomPanel.updateUI();
mainBuilderPanel.updateUI();
}
public void setTextInterface(TextInterface text) {
theText = text;
response.addActionListener(theText.action);
}
public void drawMons(String name1, String name2) {
animationPanel.removeAll();
ImageIcon secImage = new ImageIcon(this.getClass().getResource("SpritesFront/" + name2 + ".gif"));
secImage = new ImageIcon(secImage.getImage().getScaledInstance((int)(secImage.getIconWidth() * 1.5), (int)(secImage.getIconHeight() * 1.5), Image.SCALE_DEFAULT));
Icon icon = secImage;
p2Gif = new JLabel(icon);
ImageIcon firstImage = new ImageIcon(this.getClass().getResource("SpritesBack/" + name1 + "-back.gif"));
firstImage = new ImageIcon(firstImage.getImage().getScaledInstance((int)(firstImage.getIconWidth() * 1.5), (int)(firstImage.getIconHeight() * 1.5), Image.SCALE_DEFAULT));
Icon icon2 = firstImage;
p1Gif = new JLabel(icon2);
animationPanel.add(healthBar2);
animationPanel.add(p2Gif);
animationPanel.add(p1Gif);
animationPanel.add(healthBar1);
updateAll();
}
public void fillPortions(int x) {
JLabel [] labels = new JLabel[x];
for (int i = 0; i < x; i ++) {
labels[i] = new JLabel();
animationPanel.add(labels[i]);
}
}
public void refreshHealthBar(int health, int total, int pNum, int mon) {
if (pNum == 1) {
if (p1MonNum != mon && p1MonNum != -1) {
p1MonNum = mon;
health1 = health;
total1 = total;
healthBar1.setHealth(health);
healthBar1.setTotal(total);
redoHealthPanel();
}
else {
p1MonNum = mon;
healthBar1.setTotal(total);;
while (health < health1) {
healthBar1.setHealth(health1);
redoHealthPanel();
health1--;
}
while (health > health1) {
healthBar1.setHealth(health1);
redoHealthPanel();
health1++;
}
}
}
else {
if (p2MonNum != mon && p2MonNum != -1) {
p2MonNum = mon;
health2 = health;
total2 = total;
healthBar2.setHealth(health);
healthBar2.setTotal(total);
redoHealthPanel();
updateAll();
}
else {
p2MonNum = mon;
healthBar2.setTotal(total);
while (health < health2) {
healthBar2.setHealth(health2);
redoHealthPanel();
health2--;
}
while (health > health2) {
healthBar2.setHealth(health2);
redoHealthPanel();
health2++;
}
}
}
}
private void redoHealthPanel () {
animationPanel.removeAll();
animationPanel.add(healthBar2);
animationPanel.add(p2Gif);
animationPanel.add(p1Gif);
animationPanel.add(healthBar1);
updateAll();
try {
TimeUnit.MILLISECONDS.sleep(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private String validatePokemon() {
String answer = "";
String tempMonNames [] = new String[6];
boolean invalidMove = false;
for (int i = 0; i < monPanels.length; i ++) {
String currentName = names[i].getText();
if (currentName.isEmpty()) {
answer = "You must have 6 Pokemon on your team but you can have less than 4 moves";
return answer;
}
for (String element : tempMonNames) {
if (element == null) {
continue;
} else if (currentName.equals(element)) {
answer = "You have duplicate Pokemon on your team";
return answer;
}
}
if (!info.validPokemon(currentName)) {
answer += "Pokemon #" + (i + 1) + " is invalid\n";
} else {
tempMonNames[i] = currentName;
}
int count = 0;
for (int k = 0; k < moves[i].length; k++) {
if (moves[i][k].getText().isEmpty()) {
count++;
}
if (!info.validMove(moves[i][k].getText().replace(" ", "").toLowerCase(), currentName)) {
answer += "Pokemon #" + (i + 1) + ", move #" + (k + 1) + " is invalid\n";
invalidMove = true;
}
if (count >= 4) {
answer += "Pokemon #" + (i + 1) + " has no moves\n";
break;
}
}
}
if (invalidMove) {
answer += "***Please keep in mind only damaging moves without recoil are allowed, if there aren't enough for 4 moves, leave fields blank***";
}
return answer;
}
#Override
public void actionPerformed(ActionEvent e) {
if (validatePokemon().isEmpty()) {
JOptionPane.showMessageDialog(null, "Confirmed" , "", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(null, validatePokemon() , "", JOptionPane.ERROR_MESSAGE);
}
}
#Override
public void caretUpdate(CaretEvent e) {
for (int i = 0; i < names.length; i ++) {
if (info.validPokemon(names[i].getText()) && tempImages[i].getParent() == null) {
ImageIcon temp = new ImageIcon(this.getClass().getResource("SpritesFront/" + names[i].getText().replace(" ", "").replace(":", "").replace("'", "").replace(".", "").replace("-", "").toLowerCase() + ".gif"));
temp = new ImageIcon(temp.getImage().getScaledInstance((int)(temp.getIconWidth() * 1.5), (int)(temp.getIconHeight() * 1.5), Image.SCALE_DEFAULT));
Icon icon = temp;
imagePanels[i].remove(tempImages[i]);
tempImages[i] = new JLabel(icon);
imagePanels[i].add(tempImages[i]);
updateAll();
} else if (!info.validPokemon(names[i].getText())){
imagePanels[i].remove(tempImages[i]);
updateAll();
}
}
}
}
This is set up for the window:
GraphicsPanel window = new GraphicsPanel("Pokemon");
window.setBounds(0, 0, 1440, 830);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
This is where the getX() and getY() are getting called:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
public class AutoSuggestor {
private final JTextComponent textComp;
private JPanel suggestionsPanel;
private JWindow autoSuggestionPopUpWindow;
private String typedWord;
private final ArrayList<String> dictionary = new ArrayList<>();
private JTextField textField;
private int currentIndexOfSpace, tW, tH;
private DocumentListener documentListener = new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
#Override
public void removeUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
#Override
public void changedUpdate(DocumentEvent de) {
checkForAndShowSuggestions();
}
};
private final Color suggestionsTextColor;
private final Color suggestionFocusedColor;
public AutoSuggestor(JTextComponent textComp, ArrayList<String> words, Color popUpBackground, Color textColor, Color suggestionFocusedColor, float opacity) {
this.textComp = textComp;
this.suggestionsTextColor = textColor;
this.suggestionFocusedColor = suggestionFocusedColor;
this.textComp.getDocument().addDocumentListener(documentListener);
setDictionary(words);
typedWord = "";
currentIndexOfSpace = 0;
tW = 0;
tH = 0;
autoSuggestionPopUpWindow = new JWindow();
autoSuggestionPopUpWindow.setOpacity(opacity);
suggestionsPanel = new JPanel();
suggestionsPanel.setLayout(new GridLayout(0, 1));
suggestionsPanel.setBackground(popUpBackground);
addKeyBindingToRequestFocusInPopUpWindow();
}
private void addKeyBindingToRequestFocusInPopUpWindow() {
textComp.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
textComp.getActionMap().put("Down released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {//focuses the first label on popwindow
for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
((SuggestionLabel) suggestionsPanel.getComponent(i)).setFocused(true);
autoSuggestionPopUpWindow.toFront();
autoSuggestionPopUpWindow.requestFocusInWindow();
suggestionsPanel.requestFocusInWindow();
suggestionsPanel.getComponent(i).requestFocusInWindow();
break;
}
}
}
});
suggestionsPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "Down released");
suggestionsPanel.getActionMap().put("Down released", new AbstractAction() {
int lastFocusableIndex = 0;
#Override
public void actionPerformed(ActionEvent ae) {//allows scrolling of labels in pop window (I know very hacky for now :))
ArrayList<SuggestionLabel> sls = getAddedSuggestionLabels();
int max = sls.size();
if (max > 1) {//more than 1 suggestion
for (int i = 0; i < max; i++) {
SuggestionLabel sl = sls.get(i);
if (sl.isFocused()) {
if (lastFocusableIndex == max - 1) {
lastFocusableIndex = 0;
sl.setFocused(false);
autoSuggestionPopUpWindow.setVisible(false);
setFocusToTextField();
checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
} else {
sl.setFocused(false);
lastFocusableIndex = i;
}
} else if (lastFocusableIndex <= i) {
if (i < max) {
sl.setFocused(true);
autoSuggestionPopUpWindow.toFront();
autoSuggestionPopUpWindow.requestFocusInWindow();
suggestionsPanel.requestFocusInWindow();
suggestionsPanel.getComponent(i).requestFocusInWindow();
lastFocusableIndex = i;
break;
}
}
}
} else {//only a single suggestion was given
autoSuggestionPopUpWindow.setVisible(false);
setFocusToTextField();
checkForAndShowSuggestions();//fire method as if document listener change occured and fired it
}
}
});
}
private void setFocusToTextField() {
textComp.requestFocusInWindow();
}
public ArrayList<SuggestionLabel> getAddedSuggestionLabels() {
ArrayList<SuggestionLabel> sls = new ArrayList<>();
for (int i = 0; i < suggestionsPanel.getComponentCount(); i++) {
if (suggestionsPanel.getComponent(i) instanceof SuggestionLabel) {
SuggestionLabel sl = (SuggestionLabel) suggestionsPanel.getComponent(i);
sls.add(sl);
}
}
return sls;
}
private void checkForAndShowSuggestions() {
typedWord = getCurrentlyTypedWord();
suggestionsPanel.removeAll();//remove previos words/jlabels that were added
//used to calcualte size of JWindow as new Jlabels are added
tW = 0;
tH = 0;
boolean added = wordTyped(typedWord);
if (!added) {
if (autoSuggestionPopUpWindow.isVisible()) {
autoSuggestionPopUpWindow.setVisible(false);
}
} else {
showPopUpWindow();
setFocusToTextField();
}
}
protected void addWordToSuggestions(String word) {
SuggestionLabel suggestionLabel = new SuggestionLabel(word, suggestionFocusedColor, suggestionsTextColor, this);
calculatePopUpWindowSize(suggestionLabel);
suggestionsPanel.add(suggestionLabel);
}
public String getCurrentlyTypedWord() {//get newest word after last white spaceif any or the first word if no white spaces
String text = textComp.getText();
String wordBeingTyped = "";
text = text.replaceAll("(\\r|\\n)", " ");
if (text.contains(" ")) {
int tmp = text.lastIndexOf(" ");
if (tmp >= currentIndexOfSpace) {
currentIndexOfSpace = tmp;
wordBeingTyped = text.substring(text.lastIndexOf(" "));
}
} else {
wordBeingTyped = text;
}
return wordBeingTyped.trim();
}
private void calculatePopUpWindowSize(JLabel label) {
//so we can size the JWindow correctly
if (tW < label.getPreferredSize().width) {
tW = label.getPreferredSize().width;
}
tH += label.getPreferredSize().height;
}
public void setTextField(JTextField textField) {
this.textField = textField;
}
private void showPopUpWindow() {
autoSuggestionPopUpWindow.getContentPane().add(suggestionsPanel);
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.setSize(tW, tH);
autoSuggestionPopUpWindow.setVisible(true);
//show the pop up
autoSuggestionPopUpWindow.setLocation(textComp.getX(), textComp.getY() + textComp.getHeight());
autoSuggestionPopUpWindow.setMinimumSize(new Dimension(textComp.getWidth(), 30));
autoSuggestionPopUpWindow.revalidate();
autoSuggestionPopUpWindow.repaint();
}
public void setDictionary(ArrayList<String> words) {
dictionary.clear();
if (words == null) {
return;//so we can call constructor with null value for dictionary without exception thrown
}
for (String word : words) {
dictionary.add(word);
}
}
public JWindow getAutoSuggestionPopUpWindow() {
return autoSuggestionPopUpWindow;
}
public JTextComponent getTextField() {
return textComp;
}
public void addToDictionary(String word) {
dictionary.add(word);
}
boolean wordTyped(String typedWord) {
if (typedWord.isEmpty()) {
return false;
}
//System.out.println("Typed word: " + typedWord);
boolean suggestionAdded = false;
for (String word : dictionary) {//get words in the dictionary which we added
boolean fullymatches = true;
for (int i = 0; i < typedWord.length(); i++) {//each string in the word
if (!typedWord.toLowerCase().startsWith(String.valueOf(word.toLowerCase().charAt(i)), i)) {//check for match
fullymatches = false;
break;
}
}
if (fullymatches) {
addWordToSuggestions(word);
suggestionAdded = true;
}
}
return suggestionAdded;
}
}
class SuggestionLabel extends JLabel {
private boolean focused = false;
private final JWindow autoSuggestionsPopUpWindow;
private final JTextComponent textComponent;
private final AutoSuggestor autoSuggestor;
private Color suggestionsTextColor, suggestionBorderColor;
public SuggestionLabel(String string, final Color borderColor, Color suggestionsTextColor, AutoSuggestor autoSuggestor) {
super(string);
this.suggestionsTextColor = suggestionsTextColor;
this.autoSuggestor = autoSuggestor;
this.textComponent = autoSuggestor.getTextField();
this.suggestionBorderColor = borderColor;
this.autoSuggestionsPopUpWindow = autoSuggestor.getAutoSuggestionPopUpWindow();
initComponent();
}
private void initComponent() {
setFocusable(true);
setForeground(suggestionsTextColor);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
replaceWithSuggestedText();
autoSuggestionsPopUpWindow.setVisible(false);
}
});
getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "Enter released");
getActionMap().put("Enter released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
replaceWithSuggestedText();
autoSuggestionsPopUpWindow.setVisible(false);
}
});
}
public void setFocused(boolean focused) {
if (focused) {
setBorder(new LineBorder(suggestionBorderColor));
} else {
setBorder(null);
}
repaint();
this.focused = focused;
}
public boolean isFocused() {
return focused;
}
private void replaceWithSuggestedText() {
String suggestedWord = getText();
String text = textComponent.getText();
String typedWord = autoSuggestor.getCurrentlyTypedWord();
String t = text.substring(0, text.lastIndexOf(typedWord));
String tmp = t + text.substring(text.lastIndexOf(typedWord)).replace(typedWord, suggestedWord);
textComponent.setText(tmp);
}
}
The textComp.getX() and textComp.getY() in the showPopUpWindow method are the ones that are giving zeros.
After thinking about it for a while I came up with this solution and it works for me.
int x = 0;
int y = 0;
Component currentComponent = textComp;
while (currentComponent != null) {
x += currentComponent.getX();
y += currentComponent.getY();
currentComponent = currentComponent.getParent();
}
I have a menu that has a variety of buttons on display, I'm able to make the buttons call their respective JPanels when clicked. The thing is I would like to make the Jpanel slide in when its called instead of instantaneously popping in. I tried using tween engine and as Java beginner, I find it really overwhelming, so I decided to use timed animation. I was able to make the Jpanel on top to slide to one side but for some reason the next panel doesn't want to display, im really tired, can someone help please! There code is below:
public class Listener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
new Timer(0, new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainpane.setLocation(mainpane.getX() - 10, 0);
if (mainpane.getX() + mainpane.getWidth() == 0)
{
((Timer) e.getSource()).stop();
System.out.println("Timer stopped");
}
}
}).start();
}
}
Sliding panels can be tricky. Here is some starter code. Modify to fit
your needs. Add error checking and exception handling as necessary.
This example uses JButtons and a JTree as content but you can use just about any type of content.
Usage:
static public void main(final String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
final JFrame jFrame = new JFrame() {
{
final PanelSlider42<JFrame> slider = new PanelSlider42<JFrame>(this);
final JPanel jPanel = slider.getBasePanel();
slider.addComponent(new JButton("1"));
slider.addComponent(new JButton("22"));
slider.addComponent(new JButton("333"));
slider.addComponent(new JButton("4444"));
getContentPane().add(jPanel);
setSize(300, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setVisible(true);
}
};
}
});
}
The impl is lengthy ...
package com.java42.example.code;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
public class PanelSlider42<ParentType extends Container> {
private static final int RIGHT = 0x01;
private static final int LEFT = 0x02;
private static final int TOP = 0x03;
private static final int BOTTOM = 0x04;
private final JPanel basePanel = new JPanel();
private final ParentType parent;
private final Object lock = new Object();
private final ArrayList<Component> jPanels = new ArrayList<Component>();
private final boolean useSlideButton = true;
private boolean isSlideInProgress = false;
private final JPanel glassPane;
{
glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.addMouseListener(new MouseAdapter() {
});
glassPane.addMouseMotionListener(new MouseMotionAdapter() {
});
glassPane.addKeyListener(new KeyAdapter() {
});
}
public PanelSlider42(final ParentType parent) {
if (parent == null) {
throw new RuntimeException("ProgramCheck: Parent can not be null.");
}
if ((parent instanceof JFrame) || (parent instanceof JDialog) || (parent instanceof JWindow) || (parent instanceof JPanel)) {
}
else {
throw new RuntimeException("ProgramCheck: Parent type not supported. " + parent.getClass().getSimpleName());
}
this.parent = parent;
attach();
basePanel.setSize(parent.getSize());
basePanel.setLayout(new BorderLayout());
if (useSlideButton) {
final JPanel statusPanel = new JPanel();
basePanel.add(statusPanel, BorderLayout.SOUTH);
statusPanel.add(new JButton("Slide Left") {
private static final long serialVersionUID = 9204819004142223529L;
{
setMargin(new Insets(0, 0, 0, 0));
}
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slideLeft();
}
});
}
});
statusPanel.add(new JButton("Slide Right") {
{
setMargin(new Insets(0, 0, 0, 0));
}
private static final long serialVersionUID = 9204819004142223529L;
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slideRight();
}
});
}
});
statusPanel.add(new JButton("Slide Up") {
{
setMargin(new Insets(0, 0, 0, 0));
}
private static final long serialVersionUID = 9204819004142223529L;
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slideTop();
}
});
}
});
statusPanel.add(new JButton("Slide Down") {
{
setMargin(new Insets(0, 0, 0, 0));
}
private static final long serialVersionUID = 9204819004142223529L;
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slideBottom();
}
});
}
});
}
}
public JPanel getBasePanel() {
return basePanel;
}
private void attach() {
final ParentType w = this.parent;
if (w instanceof JFrame) {
final JFrame j = (JFrame) w;
if (j.getContentPane().getComponents().length > 0) {
throw new RuntimeException("ProgramCheck: Parent already contains content.");
}
j.getContentPane().add(basePanel);
}
if (w instanceof JDialog) {
final JDialog j = (JDialog) w;
if (j.getContentPane().getComponents().length > 0) {
throw new RuntimeException("ProgramCheck: Parent already contains content.");
}
j.getContentPane().add(basePanel);
}
if (w instanceof JWindow) {
final JWindow j = (JWindow) w;
if (j.getContentPane().getComponents().length > 0) {
throw new RuntimeException("ProgramCheck: Parent already contains content.");
}
j.getContentPane().add(basePanel);
}
if (w instanceof JPanel) {
final JPanel j = (JPanel) w;
if (j.getComponents().length > 0) {
throw new RuntimeException("ProgramCheck: Parent already contains content.");
}
j.add(basePanel);
}
}
public void addComponent(final Component component) {
if (jPanels.contains(component)) {
}
else {
jPanels.add(component);
if (jPanels.size() == 1) {
basePanel.add(component);
}
component.setSize(basePanel.getSize());
component.setLocation(0, 0);
}
}
public void removeComponent(final Component component) {
if (jPanels.contains(component)) {
jPanels.remove(component);
}
}
public void slideLeft() {
slide(LEFT);
}
public void slideRight() {
slide(RIGHT);
}
public void slideTop() {
slide(TOP);
}
public void slideBottom() {
slide(BOTTOM);
}
private void enableUserInput(final ParentType w) {
if (w instanceof JFrame) {
((JFrame) w).getGlassPane().setVisible(false);
}
if (w instanceof JDialog) {
((JDialog) w).getGlassPane().setVisible(false);
}
if (w instanceof JWindow) {
((JWindow) w).getGlassPane().setVisible(false);
}
}
private void disableUserInput(final ParentType w) {
if (w instanceof JFrame) {
((JFrame) w).setGlassPane(glassPane);
}
if (w instanceof JDialog) {
((JDialog) w).setGlassPane(glassPane);
}
if (w instanceof JWindow) {
((JWindow) w).setGlassPane(glassPane);
}
glassPane.setVisible(true);
}
private void enableTransparentOverylay() {
if (parent instanceof JFrame) {
((JFrame) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
parent.remove(basePanel);
parent.validate();
}
if (parent instanceof JDialog) {
((JDialog) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
parent.remove(basePanel);
parent.validate();
}
if (parent instanceof JWindow) {
((JWindow) parent).getContentPane().setBackground(jPanels.get(0).getBackground());
parent.remove(basePanel);
parent.validate();
}
}
private void slide(final int slideType) {
if (!isSlideInProgress) {
isSlideInProgress = true;
final Thread t0 = new Thread(new Runnable() {
#Override
public void run() {
parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
disableUserInput(parent);
slide(true, slideType);
enableUserInput(parent);
parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
isSlideInProgress = false;
}
});
t0.setDaemon(true);
t0.start();
}
else {
Toolkit.getDefaultToolkit().beep();
}
}
private void slide(final boolean useLoop, final int slideType) {
if (jPanels.size() < 2) {
System.err.println("Not enough panels");
return;
}
synchronized (lock) {
Component componentOld = null;
Component componentNew = null;
if ((slideType == LEFT) || (slideType == TOP)) {
componentNew = jPanels.remove(jPanels.size() - 1);
componentOld = jPanels.get(0);
jPanels.add(0, componentNew);
}
if ((slideType == RIGHT) || (slideType == BOTTOM)) {
componentOld = jPanels.remove(0);
jPanels.add(componentOld);
componentNew = jPanels.get(0);
}
final int w = componentOld.getWidth();
final int h = componentOld.getHeight();
final Point p1 = componentOld.getLocation();
final Point p2 = new Point(0, 0);
if (slideType == LEFT) {
p2.x += w;
}
if (slideType == RIGHT) {
p2.x -= w;
}
if (slideType == TOP) {
p2.y += h;
}
if (slideType == BOTTOM) {
p2.y -= h;
}
componentNew.setLocation(p2);
int step = 0;
if ((slideType == LEFT) || (slideType == RIGHT)) {
step = (int) (((float) parent.getWidth() / (float) Toolkit.getDefaultToolkit().getScreenSize().width) * 40.f);
}
else {
step = (int) (((float) parent.getHeight() / (float) Toolkit.getDefaultToolkit().getScreenSize().height) * 20.f);
}
step = step < 5 ? 5 : step;
basePanel.add(componentNew);
basePanel.revalidate();
if (useLoop) {
final int max = (slideType == LEFT) || (slideType == RIGHT) ? w : h;
final long t0 = System.currentTimeMillis();
for (int i = 0; i != (max / step); i++) {
switch (slideType) {
case LEFT: {
p1.x -= step;
componentOld.setLocation(p1);
p2.x -= step;
componentNew.setLocation(p2);
break;
}
case RIGHT: {
p1.x += step;
componentOld.setLocation(p1);
p2.x += step;
componentNew.setLocation(p2);
break;
}
case TOP: {
p1.y -= step;
componentOld.setLocation(p1);
p2.y -= step;
componentNew.setLocation(p2);
break;
}
case BOTTOM: {
p1.y += step;
componentOld.setLocation(p1);
p2.y += step;
componentNew.setLocation(p2);
break;
}
default:
new RuntimeException("ProgramCheck").printStackTrace();
break;
}
try {
Thread.sleep(500 / (max / step));
} catch (final Exception e) {
e.printStackTrace();
}
}
final long t1 = System.currentTimeMillis();
}
componentOld.setLocation(-10000, -10000);
componentNew.setLocation(0, 0);
}
}
}
I have searched for that problem some time ago.I found this sample code somewhere - saved in my evernote for future reference. This is the shortest way to implement that when I googled that in the past
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class SlidingPanel {
JPanel panel;
public void makeUI() {
panel = new JPanel();
panel.setBackground(Color.RED);
panel.setBounds(0, 0, 400, 400);
JButton button = new JButton("Click");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
((JButton) e.getSource()).setEnabled(false);
new Timer(1, new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.setLocation(panel.getX() - 1, 0);
if (panel.getX() + panel.getWidth() == 0) {
((Timer) e.getSource()).stop();
System.out.println("Timer stopped");
}
}
}).start();
}
});
panel.add(button);
JFrame frame = new JFrame("Sliding Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.add(panel);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SlidingPanel().makeUI();
}
});
}
}
however I am not sure where I am supposed to enter the whoWins() method. Do I enter this method in the actionperformed Method of the buttons or do i need to something different. Please help.
public class TTT extends JFrame implements ActionListener {
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
private int count = 0;
int symbolCount = 0;
private boolean win = false;
public TTT() {
title = new JLabel("Welcome to my Tic Tac Toe Game!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
//Determines who wins using for the horizontal rows.
if (buttons[0].getText() == buttons[1].getText() && buttons[1].getText() == buttons[2].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[3].getText() == buttons[4].getText() && buttons[4].getText() == buttons[5].getText() && buttons[3].getText() != "") {
win = true;
} else if (buttons[6].getText() == buttons[7].getText() && buttons[7].getText() == buttons[8].getText() && buttons[6].getText() != "") {
win = true;
} //Determines the verticles wins
else if (buttons[0].getText() == buttons[3].getText() && buttons[3].getText() == buttons[6].getText() && buttons[0].getText() != "") {
win = true;
} else if (buttons[1].getText() == buttons[4].getText() && buttons[4].getText() == buttons[7].getText() && buttons[1].getText() != "") {
win = true;
} else if (buttons[2].getText() == buttons[5].getText() && buttons[5].getText() == buttons[8].getText() && buttons[2].getText() != "") {
win = true;
}
// Diagnol Wins
else if (buttons[0].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[8].getText()&& buttons[0].getText()!= "") {
win = true;
}else if (buttons[2].getText()==buttons[4].getText()&&buttons[4].getText()==buttons[6].getText()&& buttons[1].getText()!= "") {
win = true;
}else {
win = false;
}
//who won
if (win = true) {
JOptionPane.showMessageDialog(null, "wins");
}else if (count == 9 && win == false) {
JOptionPane.showMessageDialog(null, "Tie game");
}
}
public static void main(String[] args) {
TTT ref1 = new TTT();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
// ref1.whoWins();
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
for (JButton button : buttons) {
if (button == e.getSource()) {
if (symbolCount % 2 == 0) {
button.setText("X");
button.setEnabled(false);
} else {
button.setText("O");
button.setEnabled(false);
}
}
}
if (count >= buttons.length) {
JOptionPane.showMessageDialog(null, "End");
}
symbolCount++;
}
}
If you really want to do this right, then I suggest making some big changes, some M-V-C type changes:
First and foremost, separate out the logic of the game from the game GUI. This would mean that the code that determines who wins should not be in any code that contains GUI type code. This will be your "model"
Next you should never have GUI code implement listener interfaces, so try to get that out of the GUI and possibly have it go into its own class, the "Control" class.
Finally the GUI or "View" class will concern itself with displaying the model's state and getting input from the user and transmitting this input to the control.
For example,...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class TicTacToeMain {
private static void createAndShowGui() {
TttView view = null;
try {
view = new TttView();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
TttModel model = new TttModel();
new TttControl(model, view);
JFrame frame = new JFrame("Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(view.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum TttPiece {
EMPTY, X, O
}
class TttView {
public static final String IMAGE = "/imgFolder/TicTacToe.png";
private static final int GAP = 5;
private JPanel mainPanel = new JPanel();
private JPanel tttPanel = new JPanel();
private Map<TttPiece, Icon> iconMap = new EnumMap<>(TttPiece.class);
private JLabel[][] grid = new JLabel[TttModel.ROWS][TttModel.COLS];
private TttControl control;
public TttView() throws IOException {
BufferedImage img = ImageIO.read(getClass().getResourceAsStream(IMAGE));
Icon[] imgIcons = splitImg(img);
iconMap.put(TttPiece.X, imgIcons[0]);
iconMap.put(TttPiece.O, imgIcons[1]);
iconMap.put(TttPiece.EMPTY, createEmptyIcon(imgIcons[0]));
tttPanel.setLayout(new GridLayout(grid.length, grid[0].length, GAP, GAP));
tttPanel.setBackground(Color.black);
MyMouseAdapter mouseAdapter = new MyMouseAdapter();
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
grid[row][col] = new JLabel(iconMap.get(TttPiece.EMPTY));
grid[row][col].setOpaque(true);
grid[row][col].setBackground(Color.LIGHT_GRAY);
grid[row][col].addMouseListener(mouseAdapter);
tttPanel.add(grid[row][col]);
}
}
JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));
btnPanel.add(new JButton(new ClearAction("Clear", KeyEvent.VK_C)));
btnPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
int blGap = 2;
mainPanel.setLayout(new BorderLayout(blGap, blGap));
mainPanel.setBorder(BorderFactory.createEmptyBorder(blGap, blGap, blGap,
blGap));
mainPanel.add(tttPanel, BorderLayout.CENTER);
mainPanel.add(btnPanel, BorderLayout.SOUTH);
}
public void setControl(TttControl control) {
this.control = control;
}
public JComponent getMainPanel() {
return mainPanel;
}
private Icon createEmptyIcon(Icon icon) {
int width = icon.getIconWidth();
int height = icon.getIconHeight();
BufferedImage img = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
return new ImageIcon(img);
}
private Icon[] splitImg(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
int gap = 5;
Icon[] icons = new ImageIcon[2];
icons[0] = new ImageIcon(img.getSubimage(0, 0, w / 2 - gap, h / 2 - gap));
icons[1] = new ImageIcon(img.getSubimage(w / 2 + gap, 0, w / 2 - gap, h
/ 2 - gap));
return icons;
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (control == null) {
return;
}
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[row].length; col++) {
if (grid[row][col] == e.getSource()) {
control.gridPress(row, col);
}
}
}
}
}
private class ClearAction extends AbstractAction {
public ClearAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.clear();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent evt) {
if (control != null) {
control.exit(evt);
}
}
}
public void setGridIcon(int row, int col, TttPiece tttPiece) {
grid[row][col].setIcon(iconMap.get(tttPiece));
}
}
class TttControl {
private TttModel model;
private TttView view;
public TttControl(TttModel model, TttView view) {
this.model = model;
this.view = view;
view.setControl(this);
model.addPropertyChangeListener(new ModelListener());
}
public void exit(ActionEvent evt) {
Window win = SwingUtilities
.getWindowAncestor((Component) evt.getSource());
win.dispose();
}
public void gridPress(int row, int col) {
try {
model.gridPress(row, col);
} catch (TttException e) {
// TODO: notify user
// e.printStackTrace();
}
}
public void clear() {
model.clear();
}
private class ModelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (TttModel.GRID_POSITION.equals(evt.getPropertyName())) {
TttPiece[][] tttGrid = model.getTttGrid();
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
view.setGridIcon(row, col, tttGrid[row][col]);
}
}
}
}
}
}
class TttModel {
public static final int ROWS = 3;
public static final int COLS = ROWS;
public static final String GRID_POSITION = "grid position";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private TttPiece[][] tttGrid = new TttPiece[ROWS][COLS];
private TttPiece player = TttPiece.X;
private boolean gameOver;
public TttModel() {
clear();
}
public void setGridPosition(int row, int col, TttPiece piece)
throws TttException {
if (gameOver) {
return;
}
if (tttGrid[row][col] == TttPiece.EMPTY) {
tttGrid[row][col] = piece;
checkForWin(row, col, piece);
nextPlayer();
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
} else {
String message = "Invalid setGridPosition for row: %d, col: %d, piece: %s. "
+ "Spot already occupied by piece: %s";
message = String.format(message, row, col, piece, tttGrid[row][col]);
throw new TttException(message);
}
}
public TttPiece[][] getTttGrid() {
return tttGrid;
}
public void gridPress(int row, int col) throws TttException {
setGridPosition(row, col, player);
}
public void nextPlayer() {
player = player == TttPiece.X ? TttPiece.O : TttPiece.X;
}
private void checkForWin(int row, int col, TttPiece piece) {
// TODO finish
}
public void clear() {
for (int row = 0; row < tttGrid.length; row++) {
for (int col = 0; col < tttGrid[row].length; col++) {
tttGrid[row][col] = TttPiece.EMPTY;
}
}
player = TttPiece.X;
pcSupport.firePropertyChange(GRID_POSITION, null, tttGrid);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
#SuppressWarnings("serial")
class TttException extends Exception {
public TttException() {
super();
}
public TttException(String message) {
super(message);
}
}
Using for my images:
With GUI looking like:
I am also interested in writing a Tic Tac Toe game, so I copied your code, and did a little modification, and it passed test, check following:
package eric.j2se.swing;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* <p>
* Simple game of Tic Tac Toe.
* </p>
*
* #author eric
* #date Apr 16, 2014 11:03:48 AM
*/
#SuppressWarnings("serial")
public class TicTacToe extends JFrame implements ActionListener {
// 2 players
public static final char playerX = 'X';
public static final char playerO = 'O';
// null player
public static final char playerN = 'N';
// the winer, init to null player
private Character winner = playerN;
// indicate whether game over
private boolean gameOver = false;
// count of button used,
private int count = 0;
private Character buttonPlayers[] = new Character[9];
private JButton buttons[] = new JButton[9];
private JButton exitButton;
public JLabel title;
public JPanel titlePanel, panel;
public TicTacToe() {
// init buttonPlayers
for (int i = 0; i < 9; i++) {
buttonPlayers[i] = playerN;
}
// init title
title = new JLabel("Welcome to Tic Tac Toe!");
titlePanel = new JPanel();
title.setFont(new Font(Font.SERIF, 0, 30));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.NORTH);
// init 9 button
panel = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton();
panel.add(buttons[i]);
buttons[i].setEnabled(true);
buttons[i].addActionListener(this);
}
// init exit button
this.add(panel, BorderLayout.CENTER);
JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
exitButton = new JButton("Quit");
panel1.add(exitButton);
this.add(panel1, BorderLayout.SOUTH);
exitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(WIDTH);
}
});
}
public void whoWins() {
// determine winner - horizontal rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[0 + i * 3] != playerN) && (buttonPlayers[0 + i * 3].equals(buttonPlayers[1 + i * 3]))
&& buttonPlayers[1 + i * 3].equals(buttonPlayers[2 + i * 3])) {
winner = buttonPlayers[0 + i * 3];
gameOver = true;
break;
}
}
}
// determine winner - vertical rows
if (!gameOver) {
for (int i = 0; i < 3; i++) {
if ((buttonPlayers[i + 0 * 3] != playerN) && (buttonPlayers[i + 0 * 3].equals(buttonPlayers[i + 1 * 3]))
&& buttonPlayers[i + 1 * 3].equals(buttonPlayers[i + 2 * 3])) {
winner = buttonPlayers[i + 0 * 3];
gameOver = true;
break;
}
}
}
// determine winner - diagonal rows
if (!gameOver) {
int winButtonIndex = -1;
if ((buttonPlayers[0] != playerN) && (buttonPlayers[0].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[8])) {
winButtonIndex = 0;
} else if ((buttonPlayers[2] != playerN) && (buttonPlayers[2].equals(buttonPlayers[4])) && buttonPlayers[4].equals(buttonPlayers[6])) {
winButtonIndex = 2;
}
if (winButtonIndex >= 0) {
winner = buttonPlayers[winButtonIndex];
gameOver = true;
}
}
// full
if (count == 9) {
gameOver = true;
}
if (gameOver) {
String tip = "";
switch (winner) {
case playerO:
tip = "Player O win!";
break;
case playerX:
tip = "Player X win!";
break;
default:
tip = "Draw game!";
break;
}
JOptionPane.showMessageDialog(null, tip);
}
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < buttons.length; i++) {
JButton button = buttons[i];
if (button == e.getSource()) {
Character currentPlayer = (count % 2 == 1 ? playerX : playerO);
button.setText(String.valueOf(currentPlayer));
buttonPlayers[i] = currentPlayer;
button.setEnabled(false);
break;
}
}
count++;
whoWins();
}
public static void main(String[] args) {
TicTacToe ref1 = new TicTacToe();
ref1.setTitle("Tic Tac Toe");
ref1.setVisible(true);
ref1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ref1.setSize(500, 500);
ref1.setLocationRelativeTo(null);
}
}
about when to call the win check:
check each time you click 1 of the 9 buttons,
about the flag:
I use 2 flag instead of 1 flag to indicate game over & winner, because in TTT game, draw game is very usual, after play several times, you always get draw game ...
a little suggestion to your code:
when compare string, use equals(), not ==,
define const values in variable, not write it in logic, e.g. 'O' 'X',
don't repeat code, try use logic control to make it short & easy to read & easy to maintain,
I want to create a text field that will be for dates and will have dd.mm.YYYY format. Now what I want the user to type only the numbers, not the dots to. So the field would be like:
_ _. _ _ . _ _ _ _
So when the user wants to type the date: 15.05.2010 for example, he will only type the numbers in the sequence 15052010.
Also I would like, when he presses on left or right arrow, the cursor to go from one field (not JTextField, but field in the JTextField) to the next. So lets say I have JTextField with this text in it: 15.05.2010 If the user is on the beginning and he presses the right arrow, the cursor should go to the .05 field.
I hope you understand me because right now I don't have any idea how to make this, or at least how to look for it on google.
Well, here are 4 classes that solve your problem.
In my case its version control but IP address has the same structure and its easy to modify it.
package com.demo.textfield.version;
import javax.swing.text.Document;
/**
* create documents for text fields
*/
public class DocumentsFactory {
private DocumentsFactory() {}
public static Document createIntDocument() {
return createIntDocument(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
public static Document createIntDocument(int maxValue) {
return createIntDocument(maxValue, Integer.MAX_VALUE);
}
public static Document createIntDocument(int maxValue, int maxLength) {
IntDocument intDocument = new IntDocument();
intDocument.setMaxVal(maxValue);
intDocument.setMaxLength(maxLength);
return intDocument;
}
}
in the followed class we define view:
package com.demo.textfield.version;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JPanel;
public class GridbagPanel extends JPanel {
private static final long serialVersionUID = 1L;
public static final Insets NO_INSETS = new Insets(0, 0, 0, 0);
public GridBagConstraints constraints;
private GridBagLayout layout;
public GridbagPanel() {
layout = new GridBagLayout();
constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.WEST;
constraints.insets = NO_INSETS;
setLayout(layout);
}
public void setHorizontalFill() {
constraints.fill = GridBagConstraints.HORIZONTAL;
}
public void setNoneFill() {
constraints.fill = GridBagConstraints.NONE;
}
public void add(Component component, int x, int y, int width, int
height, int weightX, int weightY) {
GridBagLayout gbl = (GridBagLayout) getLayout();
gbl.setConstraints(component, constraints);
add(component);
}
public void add(Component component, int x, int y, int width, int height) {
add(component, x, y, width, height, 0, 0);
}
public void setBothFill() {
constraints.fill = GridBagConstraints.BOTH;
}
public void setInsets(Insets insets) {
constraints.insets = insets;
}
}
We use a plain document that contains our main logic (your changes should be here):
package com.demo.textfield.version;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
/**
* a class for positive integers
*/
public class IntDocument extends PlainDocument {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String NUMERIC = "0123456789";
private int maxVal = -1;
private int maxLength = -1;
public IntDocument() {
this.maxVal = -1;
maxVal = Integer.MAX_VALUE;
maxLength = Integer.MAX_VALUE;
}
public void setMaxLength(int maxLength) {
if (maxLength < 0)
throw new IllegalArgumentException("maxLength<0");
this.maxLength = maxLength;
}
public void setMaxVal(int maxVal) {
this.maxVal = maxVal;
}
public void insertString
(int offset, String str, AttributeSet attr)
throws BadLocationException {
if (str == null)
return;
if (str.startsWith(" ") && offset == 0) {
beep();
str = "";
}
if (!isValidForAcceptedCharsPolicy(str))
return;
if (validateLength(offset, str) == false)
return;
if (!isValidForMaxVal(offset, str))
return;
super.insertString(offset, str, attr);
}
public boolean isValidForAcceptedCharsPolicy(String str) {
if (str.equals("")) {
beep();
return false;
}
for (int i = 0; i < str.length(); i++) {
if (NUMERIC.indexOf(String.valueOf(str.charAt(i))) == -1) {
beep();
return false;
}
}
return true;
}
public boolean isValidForMaxVal(int offset, String toAdd) {
String str_temp;
//String str_text = "";
String str1 = "";
String str2 = "";
try {
str1 = getText(0, offset);
str2 = getText(offset, getLength() - offset);
} catch (Exception e) {
e.printStackTrace();
}
int i_value;
str_temp = str1 + toAdd + str2;
//str_temp = str_temp.trim();
i_value = Integer.parseInt(str_temp);
if (i_value > maxVal) {
beep();
return false;
} else
return true;
}
private boolean validateLength(int offset, String toAdd) {
String str_temp;
//String str_text = "";
String str1 = "";
String str2 = "";
try {
str1 = getText(0, offset);
str2 = getText(offset, getLength() - offset);
} catch (Exception e) {
e.printStackTrace();
}
str_temp = str1 + toAdd + str2;
if (maxLength < str_temp.length()) {
beep();
return false;
} else
return true;
}
private void beep() {
//java.awt.Toolkit.getDefaultToolkit().beep();
}
}
And this is last one with main method that implements all above posted code and you get pretty good view. In my case I used list of 4 text fields separated by dot. You can jump from one "window" to another by using arrows or tab or dot or if your number length reached 4. It will work with implementation of FocusAdapter class:
package com.demo.textfield.version;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.FocusManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
/**
* diplays an version text field
*/
![enter image description here][1]public class VersionTextField extends GridbagPanel {
private static final long serialVersionUID = 1L;
/**
* a text field for each byte
*/
private JTextField[] textFields;
/**
* dots between text fields
*/
private JLabel[] dotsLabels;
/**
* used to calculate enable/disable color; never shown
*/
private static JTextField sampleTextField = new JTextField();
/**
* listen to changes in the byte fields
*/
private MyDocumentListener documentListener;
/**
* list of key listeners
*/
private List<KeyListener> keyListenersList;
/**
* List of Focus Adapter that select all data in JTextFiled during action
* */
private List<FocusAdapter> focusAdapterList;
/**
* list of key listeners
*/
private List<FocusListener> focusListenersList;
private int maxHeight = 0;
public VersionTextField() {
this(4);
}
/**
* #param byteCount
* number of bytes to display
*/
private VersionTextField(int byteCount) {
textFields = new JTextField[byteCount];
for (int i = 0; i < textFields.length; i++) {
textFields[i] = new JTextField(4);
}
//layout
//constraints.insets = new Insets(0, 0, 0, 0);
List<JLabel> dotsLabelsList = new ArrayList<JLabel>();
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.setHorizontalAlignment(JTextField.CENTER);
Document document = DocumentsFactory.createIntDocument(9999);
textField.setDocument(document);
if (i < textFields.length-1) {
add(textField, i * 2, 0, 1, 1);
if (textField.getPreferredSize().height > maxHeight)
maxHeight = textField.getPreferredSize().height;
JLabel label = new JLabel(".");
add(label, (i * 2) + 1, 0, 1, 1);
if (label.getPreferredSize().height > maxHeight)
maxHeight = label.getPreferredSize().height;
dotsLabelsList.add(label);
} else
add(textField, i * 2, 0, 1, 1);
}
//dotsLabels = new JLabel[dotsLabelsList.size()];
dotsLabels = new JLabel[dotsLabelsList.size()];
dotsLabels = dotsLabelsList.toArray(dotsLabels);
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.setBorder(BorderFactory.createEmptyBorder());
}
//init
Color backgroundColor = UIManager.getColor("TextField.background");
setBackground(backgroundColor);
Border border = UIManager.getBorder("TextField.border");
setBorder(border);
//register listeners
for (int i = 1; i < textFields.length; i++) {
JTextField field = textFields[i];
field.addKeyListener(new BackKeyAdapter());
}
documentListener = new MyDocumentListener();
for (int i = 0; i < textFields.length - 1; i++) {
JTextField field = textFields[i];
field.getDocument().addDocumentListener(documentListener);
field.addKeyListener(new ForwardKeyAdapter());
}
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.addKeyListener(new MyKeyListener());
}
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.addFocusListener(new MyFocusAdapter());
}
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.addFocusListener(new MyFocusAdapter());
}
keyListenersList = new ArrayList<KeyListener>();
focusListenersList = new ArrayList<FocusListener>();
focusAdapterList = new ArrayList<FocusAdapter>();
}
public synchronized void addKeyListener(KeyListener l) {
super.addKeyListener(l);
keyListenersList.add(l);
}
public synchronized void addFocusListener(FocusListener l) {
super.addFocusListener(l);
if (focusListenersList != null)
focusListenersList.add(l);
}
public synchronized void removeKeyListener(KeyListener l) {
super.removeKeyListener(l);
if (focusListenersList != null)
keyListenersList.remove(l);
}
public synchronized void removeFocusListener(FocusListener l) {
super.removeFocusListener(l);
keyListenersList.remove(l);
}
public void setEnabled(boolean b) {
super.setEnabled(b);
sampleTextField.setEnabled(b);
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.setEnabled(b);
}
for (int i = 0; i < dotsLabels.length; i++) {
JLabel dotsLabel = dotsLabels[i];
dotsLabel.setEnabled(b);
}
setBackground(sampleTextField.getBackground());
setForeground(sampleTextField.getForeground());
setBorder(sampleTextField.getBorder());
}
public void requestFocus() {
super.requestFocus();
textFields[0].requestFocus();
}
public void setEditable(boolean b) {
sampleTextField.setEditable(b);
setBackground(sampleTextField.getBackground());
setForeground(sampleTextField.getForeground());
setBorder(sampleTextField.getBorder());
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.setEditable(b);
}
for (int i = 0; i < dotsLabels.length; i++) {
JLabel dotsLabel = dotsLabels[i];
dotsLabel.setForeground(sampleTextField.getForeground());
}
}
public boolean isFieldEmpty() {
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
String sCell = textField.getText().trim();
if (!(sCell.equals("")))
return false;
}
return true;
}
public Dimension getPreferredSize() {
if (super.getPreferredSize().height > maxHeight)
maxHeight = super.getPreferredSize().height;
return new Dimension(super.getPreferredSize().width, maxHeight);
}
/**
* clears current text in text fiekd
*/
private void reset() {
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.getDocument().removeDocumentListener(documentListener);
textField.setText("");
textField.getDocument().addDocumentListener(documentListener);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("test");
VersionTextField ipTextField = new VersionTextField();
ipTextField.setText("9.1.23.1479");
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(ipTextField);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void setText(String version) {
if (version == null || "".equals(version) || "null".equals(version))
reset();
else {
setVer(version.split("[.]"));
}
}
private void setVer(String[] ver) {
if (ver == null) {
reset();
return;
}
Enumeration<String> enumeration = Collections.enumeration(Arrays.asList(ver));
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
String s = (String) enumeration.nextElement();
textField.getDocument().removeDocumentListener(documentListener);
textField.setText(s);
textField.getDocument().addDocumentListener(documentListener);
}
}
public void setToolTipText(String toolTipText) {
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
textField.setToolTipText(toolTipText);
}
}
private class MyDocumentListener implements DocumentListener {
#Override
public void insertUpdate(DocumentEvent e) {
Document document = e.getDocument();
try {
JTextField textField = (JTextField) FocusManager.getCurrentManager().getFocusOwner();
String s = document.getText(0, document.getLength());
if (s.length() == 4){ // && textField.getCaretPosition() == 2) {
textField.transferFocus();
}
} catch (BadLocationException e1) {
e1.printStackTrace();
return;
}
}
public void removeUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent e) {
// Document document = e.getDocument();
// try {
// Component component = FocusManager.getCurrentManager().getFocusOwner();
// String s = document.getText(0, document.getLength());
//
// // get selected integer
// int valueInt = Integer.parseInt(s);
//
// if (valueInt > 25) {
// component.transferFocus();
// }
//
// } catch (BadLocationException e1) {
// e1.printStackTrace();
// return;
// }
}
}
private class BackKeyAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
JTextField textField = (JTextField) e.getComponent();
if (textField.getCaretPosition() == 0
&& KeyEvent.VK_LEFT == e.getKeyCode()
&& e.getModifiers() == 0)
textField.transferFocusBackward();
if (textField.getCaretPosition() == 0
&& KeyEvent.VK_BACK_SPACE == e.getKeyCode()
&& e.getModifiers() == 0) {
textField.transferFocusBackward();
}
}
}
private class ForwardKeyAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
JTextField textField = (JTextField) e.getComponent();
if (KeyEvent.VK_RIGHT == e.getKeyCode() && e.getModifiers() == 0) {
int length = textField.getText().length();
int caretPosition = textField.getCaretPosition();
if (caretPosition == length) {
textField.transferFocus();
e.consume();
}
}
if (e.getKeyChar() == '.' &&
textField.getText().trim().length() != 0) {
textField.setText(textField.getText().trim());
textField.transferFocus();
e.consume();
}
}
}
/**
* #return current text in ip text field
*/
public String getText() {
StringBuffer buffer = new StringBuffer();
String ipResult;
for (int i = 0; i < textFields.length; i++) {
JTextField textField = textFields[i];
if(textField.getText().trim().equals("")){
return "";
}
buffer.append(Integer.parseInt(textField.getText()));
if (i < textFields.length - 1){
buffer.append('.');
}
}
ipResult = buffer.toString();
return ipResult;
}
/**
* general purpose key listener
*/
private class MyKeyListener implements KeyListener {
public void keyPressed(KeyEvent e) {
for (int i = 0; i < keyListenersList.size(); i++) {
KeyListener keyListener = keyListenersList.get(i);
keyListener.keyPressed(new KeyEvent(VersionTextField.this,
e.getID(), e.getWhen(), e.getModifiers(), e
.getKeyCode(), e.getKeyChar(), e
.getKeyLocation()));
}
}
public void keyReleased(KeyEvent e) {
for (int i = 0; i < keyListenersList.size(); i++) {
KeyListener keyListener = keyListenersList.get(i);
keyListener.keyReleased(new KeyEvent(VersionTextField.this, e
.getID(), e.getWhen(), e.getModifiers(),
e.getKeyCode(), e.getKeyChar(), e.getKeyLocation()));
}
}
public void keyTyped(KeyEvent e) {
for (int i = 0; i < keyListenersList.size(); i++) {
KeyListener keyListener = keyListenersList.get(i);
keyListener.keyTyped(new KeyEvent(VersionTextField.this, e.getID(),
e.getWhen(), e.getModifiers(), e.getKeyCode(), e
.getKeyChar(), e.getKeyLocation()));
}
}
}
private class MyFocusAdapter extends FocusAdapter {
public void focusGained(FocusEvent e) {
for (int i = 0; i < focusListenersList.size(); i++) {
FocusListener focusListener = focusListenersList.get(i);
focusListener.focusGained(new FocusEvent(
VersionTextField.this,
e.getID(),
e.isTemporary(),
e.getOppositeComponent()
));
}
if(e.getComponent() instanceof javax.swing.JTextField){
highlightText((JTextField)e.getSource());
}
}
public void focusLost(FocusEvent e) {
for (int i = 0; i < focusListenersList.size(); i++) {
FocusListener focusListener = focusListenersList.get(i);
focusListener.focusLost(new FocusEvent(
VersionTextField.this,
e.getID(),
e.isTemporary(),
e.getOppositeComponent()
));
}
}
public void highlightText(javax.swing.JTextField ctr){
//ctr.setSelectionColor(Color.BLUE);
//ctr.setSelectedTextColor(Color.WHITE);
ctr.setSelectionStart(0);
ctr.setSelectionEnd(ctr.getText().length());
System.out.println(ctr.getText());
}
}
}
here a view what we got:
here you go
JFormattedTextField