Reputation: 6352
So, I have a keyListener in my program. As soon as it's activated, it draws another component on screen.
What happens is the newest component gets drawn on screen in a place it shouldn't be or wrongly sized (just for a split second) and then snaps to it's designated location and size and everything looks great.
Is there a way to instruct my program to calculate position and size of the component prior to drawing it on screen to avoid that flicker?
package core;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
@SuppressWarnings("serial")
class DefaultFont extends Font
{
public DefaultFont()
{
super("Arial", PLAIN, 20);
}
}
@SuppressWarnings("serial")
class Page extends JPanel
{
public JPanel largePage;
public int content;
public Page(JPanel panel, int index)
{
largePage = new JPanel();
largePage.setLayout(new BoxLayout(largePage, BoxLayout.Y_AXIS));
largePage.setMaximumSize(new Dimension(794, 1123));
largePage.setPreferredSize(new Dimension(794, 1123));
largePage.setAlignmentX(Component.CENTER_ALIGNMENT);
largePage.setBackground(Color.WHITE);
largePage.add(new Box.Filler(new Dimension(0, 96), new Dimension(0, 96), new Dimension(0, 96)));
setMaximumSize(new Dimension(556, 931));
setBackground(Color.LIGHT_GRAY);
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new Box.Filler(new Dimension(556, 0), new Dimension(556, 931), new Dimension(556, 931)));
largePage.add(this);
largePage.add(new Box.Filler(new Dimension(0, 96), new Dimension(0, 96), new Dimension(0, 96)));
panel.add(largePage, index);
panel.add(new Box.Filler(new Dimension(0, 40), new Dimension(0, 40), new Dimension(0, 40)));
content = 0;
Main.pages.add(this);
}
}
@SuppressWarnings("serial")
class Heading extends JTextArea
{
public boolean type;
public AbstractDocument doc;
public ArrayList<JPanel/*Question*/> questions;
public ArrayList<JPanel/*List*/> list;
public Heading(boolean segment, Page page)
{
type = segment;
setBackground(Color.RED);
setFont(new Font("Arial", Font.BOLD, 20));
Border in = BorderFactory.createDashedBorder(Color.BLACK);
Border out = BorderFactory.createMatteBorder(0, 0, 10, 0, Color.WHITE);
setBorder(BorderFactory.createCompoundBorder(out, in));
setLineWrap(true);
setWrapStyleWord(true);
setText("Heading 1 Heading 1 Heading 1 Heading 1");
doc = (AbstractDocument)this.getDocument();
doc.setDocumentFilter(new DocumentFilter()
{
public void insertString(FilterBypass fb, int offs,String str, AttributeSet a) throws BadLocationException
{
if ((fb.getDocument().getLength() + str.length()) <= 100)
{
;
fb.insertString(offs, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 100 - fb.getDocument().getLength();
if (spaceLeft <= 0)
return;
fb.insertString(offs, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException
{
if (str.equals("\n"))
{
str = "";
}
if ((fb.getDocument().getLength() + str.length() - length) <= 100)
{
fb.replace(offs, length, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 100 - fb.getDocument().getLength() + length;
if (spaceLeft <= 0)
return;
fb.replace(offs, length, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
});
page.add(this, 0);
page.content++;
if (type)
{
questions = new ArrayList<JPanel>();
}
else
{
list = new ArrayList<JPanel>();
}
}
}
@SuppressWarnings("serial")
class Question extends JPanel
{
public JPanel questionArea, numberArea, answerArea;
public JLabel number;
public JTextArea question;
public AbstractDocument doc;
public Question(Page page, int pageNum, int index)
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBorder(BorderFactory.createMatteBorder(0, 0, 5, 0, Color.WHITE));
questionArea = new JPanel();
questionArea.setLayout(new BoxLayout(questionArea, BoxLayout.X_AXIS));
questionArea.setBorder(BorderFactory.createMatteBorder(0, 0, 8, 0, Color.WHITE));
numberArea = new JPanel();
numberArea.setLayout(new BorderLayout());
numberArea.setBackground(Color.WHITE);
number = new JLabel(pageNum+". ", JLabel.RIGHT);
number.setMinimumSize(new Dimension(100, 20));
number.setPreferredSize(new Dimension(100, 20));
number.setMaximumSize(new Dimension(100, 20));
number.setFont(new Font("Arial", Font.PLAIN, 17));
numberArea.add(number, BorderLayout.NORTH);
questionArea.add(numberArea);
question = new JTextArea();
question.setFont(new Font("Arial", Font.PLAIN, 17));
question.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
question.setLineWrap(true);
question.setWrapStyleWord(true);
question.setBackground(Color.GREEN);
question.setText("Is this the first question?");
doc = (AbstractDocument)question.getDocument();
doc.setDocumentFilter(new DocumentFilter()
{
public void insertString(FilterBypass fb, int offs,String str, AttributeSet a) throws BadLocationException
{
if ((fb.getDocument().getLength() + str.length()) <= 200)
{
;
fb.insertString(offs, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 200 - fb.getDocument().getLength();
if (spaceLeft <= 0)
return;
fb.insertString(offs, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException
{
if (str.equals("\n"))
{
str = "";
}
if ((fb.getDocument().getLength() + str.length() - length) <= 200)
{
fb.replace(offs, length, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 200 - fb.getDocument().getLength() + length;
if (spaceLeft <= 0)
return;
fb.replace(offs, length, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
});
questionArea.add(question);
add(questionArea);
answerArea = new JPanel();
answerArea.setLayout(new BoxLayout(answerArea, BoxLayout.Y_AXIS));
add(answerArea);
page.add(this, index);
page.content++;
}
}
@SuppressWarnings("serial")
class Answer extends JPanel
{
public JPanel letterArea;
public JLabel letter;
public JTextArea answer;
public char[] letters = {'a', 'b', 'c', 'd', 'e' };
public AbstractDocument doc;
public Answer(Question q, int index)
{
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
letterArea = new JPanel();
letterArea.setLayout(new BorderLayout());
letterArea.setBackground(Color.WHITE);
letter = new JLabel(letters[index-1]+") ", JLabel.RIGHT);
letter.setMinimumSize(new Dimension(150, 20));
letter.setPreferredSize(new Dimension(150, 20));
letter.setMaximumSize(new Dimension(150, 20));
letter.setFont(new Font("Arial", Font.PLAIN, 17));
letterArea.add(letter, BorderLayout.NORTH);
add(letterArea);
answer = new JTextArea();
answer.setFont(new Font("Arial", Font.PLAIN, 17));
Border in = BorderFactory.createDashedBorder(Color.BLACK);
Border out = BorderFactory.createMatteBorder(0, 0, 5, 0, Color.WHITE);
answer.setBorder(BorderFactory.createCompoundBorder(out, in));
answer.setLineWrap(true);
answer.setWrapStyleWord(true);
answer.addKeyListener(new KeyListener()
{
@Override
public void keyPressed(KeyEvent arg0)
{
new Answer((Question) ((JTextArea) arg0.getSource()).getParent().getParent().getParent(), 2);
Main.mWindow.repaint();
Main.mWindow.validate();
}
public void keyReleased(KeyEvent arg0) {}
public void keyTyped(KeyEvent arg0) {}
});
doc = (AbstractDocument)answer.getDocument();
doc.setDocumentFilter(new DocumentFilter()
{
public void insertString(FilterBypass fb, int offs,String str, AttributeSet a) throws BadLocationException
{
if ((fb.getDocument().getLength() + str.length()) <= 200)
{
;
fb.insertString(offs, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 200 - fb.getDocument().getLength();
if (spaceLeft <= 0)
return;
fb.insertString(offs, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException
{
if (str.equals("\n"))
{
str = "";
}
if ((fb.getDocument().getLength() + str.length() - length) <= 200)
{
fb.replace(offs, length, str.replaceAll("\n", " "), a);
}
else
{
int spaceLeft = 200 - fb.getDocument().getLength() + length;
if (spaceLeft <= 0)
return;
fb.replace(offs, length, str.substring(0,spaceLeft).replaceAll("\n", " "), a);
}
}
});
answer.setBackground(Color.PINK);
add(answer);
q.answerArea.add(this, index-1);
}
}
public class Main
{
public static Properties config;
public static Locale currentLocale;
public static ResourceBundle lang;
public static JFrame mWindow;
public static JMenuBar menu;
public static JMenu menuFile, menuEdit;
public static JMenuItem itmNew, itmClose, itmLoad, itmSave, itmSaveAs, itmExit, itmCut, itmCopy, itmPaste, itmProperties;
public static JDialog newDoc;
public static JLabel newDocText1, newDocText2;
public static JRadioButton questions, list;
public static ButtonGroup newDocButtons;
public static JButton newDocOk;
public static Boolean firstSegment;
public static JPanel workspace;
public static JScrollPane scroll;
public static ArrayList<Page> pages;
public static void newDocumentForm()
{
//new document dialog
mWindow.setEnabled(false);
newDoc = new JDialog(mWindow, "newDoc");
newDoc.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
newDoc.addWindowListener(new WindowListener ()
{
public void windowActivated(WindowEvent arg0) {}
public void windowClosing(WindowEvent arg0)
{
mWindow.toFront();
newDocText1 = null;
newDocText2 = null;
questions = null;
list = null;
newDocButtons = null;
newDocOk = null;
newDoc.dispose();
mWindow.setEnabled(true);
}
public void windowClosed(WindowEvent arg0) {}
public void windowDeactivated(WindowEvent arg0) {}
public void windowDeiconified(WindowEvent arg0) {}
public void windowIconified(WindowEvent arg0) {}
public void windowOpened(WindowEvent arg0) {}
});
newDoc.setSize(400, 200);
newDoc.setLocationRelativeTo(null);
newDoc.setResizable(false);
newDoc.setLayout(null);
newDoc.setVisible(true);
newDocText1 = new JLabel("newDocText1");
newDocText1.setBounds(5, 0, 400, 20);
newDocText2 = new JLabel("newDocText2");
newDocText2.setBounds(5, 20, 400, 20);
newDoc.add(newDocText1);
newDoc.add(newDocText2);
firstSegment = true;
questions = new JRadioButton("questions");
questions.setSelected(true);
questions.setFocusPainted(false);
questions.setBounds(10, 60, 400, 20);
questions.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
firstSegment = true;
}
});
list = new JRadioButton("list");
list.setFocusPainted(false);
list.setBounds(10, 80, 400, 20);
list.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
firstSegment = false;
}
});
newDoc.add(questions);
newDoc.add(list);
newDocButtons = new ButtonGroup();
newDocButtons.add(questions);
newDocButtons.add(list);
newDocOk = new JButton("ok");
newDocOk.addKeyListener(new KeyListener()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
newDocOk.doClick();
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
});
newDocOk.setFocusPainted(false);
newDocOk.setBounds(160, 120, 80, 40);
newDocOk.setMnemonic(KeyEvent.VK_ACCEPT);
newDocOk.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
createNewDocument();
}
});
newDoc.add(newDocOk);
newDocOk.requestFocus();
}
public static void createNewDocument()
{
//dispose of new document dialog
mWindow.toFront();
newDocText1 = null;
newDocText2 = null;
questions = null;
list = null;
newDocButtons = null;
newDocOk = null;
newDoc.dispose();
mWindow.setEnabled(true);
//create document display
workspace = new JPanel();
workspace.setLayout(new BoxLayout(workspace, BoxLayout.PAGE_AXIS));
workspace.add(new Box.Filler(new Dimension(0, 40), new Dimension(0, 40), new Dimension(0, 40)));
workspace.setBackground(Color.BLACK);
scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.getVerticalScrollBar().setUnitIncrement(20);
scroll.setViewportView(workspace);
pages = new ArrayList<Page>();
Page p = new Page(workspace, 1);
new Heading(true, p);
Question q = new Question(p, 1, 1);
new Answer(q, 1);
mWindow.add(scroll, BorderLayout.CENTER);
mWindow.repaint();
mWindow.validate();
}
public static void main(String[] args) throws FileNotFoundException, IOException
{
//create main window
mWindow = new JFrame("title");
mWindow.setSize(1000, 800);
mWindow.setMinimumSize(new Dimension(1000, 800));
mWindow.setLocationRelativeTo(null);
mWindow.setLayout(new BorderLayout());
mWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mWindow.setVisible(true);
//create menu bar
menu = new JMenuBar();
menuFile = new JMenu("file");
menuEdit = new JMenu("edit");
itmNew = new JMenuItem("new");
itmNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
itmNew.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
newDocumentForm();
}
});
itmClose = new JMenuItem("close");
itmClose.setActionCommand("Close");
itmClose.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, ActionEvent.CTRL_MASK));
itmLoad = new JMenuItem("load");
itmLoad.setActionCommand("Load");
itmLoad.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
itmSave = new JMenuItem("save");
itmSave.setActionCommand("Save");
itmSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
itmSaveAs = new JMenuItem("saveAs");
itmSaveAs.setActionCommand("SaveAs");
itmExit = new JMenuItem("exit");
itmExit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Add confirmation window!
System.exit(0);
}
});
itmCut = new JMenuItem("cut");
itmCut.setActionCommand("Cut");
itmCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
itmCopy = new JMenuItem("copy");
itmCopy.setActionCommand("Copy");
itmCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
itmPaste = new JMenuItem("paste");
itmPaste.setActionCommand("Paste");
itmPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));
itmProperties = new JMenuItem("properties");
itmProperties.setActionCommand("properties");
itmProperties.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));
menuFile.add(itmNew);
menuFile.add(itmClose);
menuFile.addSeparator();
menuFile.add(itmLoad);
menuFile.addSeparator();
menuFile.add(itmSave);
menuFile.add(itmSaveAs);
menuFile.addSeparator();
menuFile.add(itmExit);
menuEdit.add(itmCut);
menuEdit.add(itmCopy);
menuEdit.add(itmPaste);
menuEdit.addSeparator();
menuEdit.add(itmProperties);
menu.add(menuFile);
menu.add(menuEdit);
//create actionListener for menus
mWindow.add(menu, BorderLayout.NORTH);
mWindow.repaint();
mWindow.validate();
}
}
It's not SSCCE (it's whole set of interdependent components, replicating it in a new program would be pain in the neck, and might not even be that much shorter), but the whole thing occurs in the Answer class. You can almost ignore anything else.
P.S. To get thing draw pres ctrl+n, then enter! Then click in the pink textarea and just press a button...
P.P.S. If you hold that button, you get really cool effect... :D
Upvotes: 2
Views: 379
Reputation: 7126
You probably need to validate()
and then repaint()
in the KeyListener
. Key bindings may be a better way to go.
Upvotes: 1