Note that there are some explanatory texts on larger screens.

plurals
  1. POPrevent characters from KeyListener being added to a string
    primarykey
    data
    text
    <p>How to prevent characters from <code>KeyListener</code> being added to a string that won't render properly with <code>Graphics.drawString()</code>?</p> <p>What I am trying to prevent is characters from java.atw.event.KeyListener form being added to a string that won't render properly with java.atw.Graphics.drawString(). For instance, if I press shift my program will detect it to be an invalid character and not add it to a string that will later be rendered java.atw.Graphics.drawString(). Sure I can do a check for it but is there some easy way of doing it? Not in a way that involves 1000 character checks.</p> <p>My program is a small remake of javax.swing.JTextField. I have tried looking at the src code for that, but I couldn't find anything. Here is is (this can be added to a Frame as any swing component):</p> <pre><code>// Lots of imports public class TextField extends JComponent implements KeyListener, Runnable, MouseInputListener, ClipboardOwner, FocusListener{ private static final long serialVersionUID = 1; private String text; private int head = 0; private int draggedFrom = 0; private boolean renderHead = false; private boolean insert = false; private boolean dragging = false; private int renderOffset; private int time = 0; private int doubleClickTimer = -1; private boolean editable = true; private int historyIndex = 0; private ArrayList&lt;String&gt; history = new ArrayList&lt;String&gt;(); private boolean focus = this.hasFocus(); public TextField() { this(null); } public TextField(String text){ this.text = text == null ? "" : text; this.addMouseListener(this); this.addMouseMotionListener(this); this.addKeyListener(this); this.addFocusListener(this); this.setFocusable(true); new Thread(this).start(); this.setFont(new Font(null, 0, 40)); this.setDoubleBuffered(false); this.setVisible(true); } @Override public void run() { try{ while (focus){ Thread.sleep(1); if (doubleClickTimer != -1){ doubleClickTimer++; } if (doubleClickTimer &gt;= 250){ doubleClickTimer = -1; } time++; if (time == 500){ time = 0; renderHead = !renderHead; repaint(10 - renderOffset + (head == 0 ? 0 : this.getFontMetrics(this.getFont()).stringWidth(text.substring(0, head))), this.getHeight() / 2 - this.getFontMetrics(this.getFont()).getHeight() / 2, insert ? 5 : 2, this.getFontMetrics(this.getFont()).getHeight()); } } }catch (InterruptedException e){ e.printStackTrace(); } } @Override public void paint(Graphics gr) { Graphics2D g = (Graphics2D) gr; g.clearRect(0, 0, this.getWidth(), this.getHeight()); if (!editable){ g.setColor(Color.GRAY); g.fillRect(0, 0, this.getWidth(), this.getHeight()); } if (text != null){ g.setFont(this.getFont()); int height = this.getHeight() / 2 - g.getFontMetrics().getHeight() / 2; int width = (head == 0 ? 0 : g.getFontMetrics().stringWidth(text.substring(0, head))); if (width - renderOffset &gt; this.getWidth() - 20){ renderOffset = width - this.getWidth() + 20; }else if (renderOffset &gt; width){ renderOffset = width; }else if (renderOffset &gt; 0 &amp;&amp; g.getFontMetrics().stringWidth(text) - renderOffset &lt; this.getWidth() - 20){ renderOffset = g.getFontMetrics().stringWidth(text) - this.getWidth() + 20; if (renderOffset &lt; 0){ renderOffset = 0; } } if (draggedFrom != head &amp;&amp; focus){ g.setColor(new Color (150, 150, 255)); if (head &lt; draggedFrom){ g.fillRect(10 - renderOffset + width, height, g.getFontMetrics().stringWidth(text.substring(head, draggedFrom)) + (insert ? 5 : 2), g.getFontMetrics().getHeight()); }else{ g.fillRect(10 - renderOffset + g.getFontMetrics().stringWidth(text.substring(0, draggedFrom)), height, g.getFontMetrics().stringWidth(text.substring(draggedFrom, head)) + (insert ? 5 : 2), g.getFontMetrics().getHeight()); } } if (((editable &amp;&amp; renderHead) || dragging) &amp;&amp; focus){ g.setColor(Color.BLACK); g.fillRect(10 - renderOffset + width, height, insert ? 5 : 2, g.getFontMetrics().getHeight()); } g.setColor(Color.BLACK); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.drawString(text, 10 - renderOffset, height + g.getFontMetrics().getAscent()); } g.setColor(Color.BLACK); g.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1); g.dispose(); } @Override public void keyPressed(KeyEvent e) { if (editable){ time = -1; renderHead = true; if (e.isControlDown() &amp;&amp; (e.getKeyCode() == KeyEvent.VK_Z || e.getKeyCode() == KeyEvent.VK_Y)){ if (e.getKeyCode() == KeyEvent.VK_Z ? historyIndex &gt; 0 : history.size() &gt; historyIndex + 1){ if (e.getKeyCode() == KeyEvent.VK_Z){ historyIndex--; }else{ historyIndex++; } String s = history.get(historyIndex); head = s.length(); draggedFrom = 0; if (text.length() &gt; 0 &amp;&amp; s.length() &gt; 0 &amp;&amp; s.length() &gt; text.length()){ while (draggedFrom &lt; Math.min(text.length(), s.length()) &amp;&amp; text.charAt(draggedFrom) == s.charAt(draggedFrom)){ draggedFrom++; } int textIndex = text.length() - 1; int sIndex = s.length() - 1; while (Math.min(textIndex, sIndex) &gt;= 0 &amp;&amp; text.charAt(textIndex) == s.charAt(sIndex)){ head--; textIndex--; sIndex--; } }else{ draggedFrom = head; } text = s; repaint(); } return; }else if (e.getKeyCode() == KeyEvent.VK_RIGHT){ if (head &lt; text.length()){ head++; } this.draggedFrom = head; repaint(); return; }else if (e.getKeyCode() == KeyEvent.VK_LEFT){ if (head &gt; 0){ head--; } this.draggedFrom = head; repaint(); return; }else if (e.getKeyCode() == KeyEvent.VK_INSERT){ insert = !insert; repaint(); return; }else if (e.isControlDown() &amp;&amp; e.getKeyCode() == KeyEvent.VK_A){ if (text.length() &gt; 0){ this.head = text.length(); this.draggedFrom = 0; repaint(); } return; } if (e.getKeyCode() != KeyEvent.VK_SHIFT &amp;&amp; e.getKeyCode() != KeyEvent.VK_CONTROL &amp;&amp; e.getKeyCode() != KeyEvent.VK_ALT &amp;&amp; e.getKeyCode() != 12 &amp;&amp; e.getKeyCode() != KeyEvent.VK_ESCAPE &amp;&amp; !e.isActionKey()){ for (int i = history.size() - 1; i &gt;= historyIndex; i--){ history.remove(i); } if (history.size() &gt; 200){ history.remove(0); historyIndex--; } history.add(text); historyIndex++; if (history.size() &gt; 1 &amp;&amp; history.get(history.size() - 2).equals(history.get(history.size() - 1))){ history.remove(history.size() - 1); historyIndex--; } } if (e.getKeyCode() == KeyEvent.VK_ENTER){ for (ActionListener a : listenerList.getListeners(ActionListener.class)){ a.actionPerformed(new ActionEvent(this, 0, text)); } }else if (e.isControlDown() &amp;&amp; e.getKeyCode() == KeyEvent.VK_C){ if (draggedFrom != head){ Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); board.setContents(new StringSelection(draggedFrom &lt; head ? text.substring(draggedFrom, head) : text.substring(head, draggedFrom)), this); } }else if (e.isControlDown() &amp;&amp; e.getKeyCode() == KeyEvent.VK_V){ Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); if (board.isDataFlavorAvailable(DataFlavor.stringFlavor)){ try{ String clipboard = (String) board.getData(DataFlavor.stringFlavor); if (draggedFrom != head){ if (head &lt;= draggedFrom){ text = text.substring(0, head) + clipboard + text.substring(draggedFrom); draggedFrom = head; head += clipboard.length(); }else{ text = text.substring(0, draggedFrom) + clipboard + text.substring(head); head = draggedFrom + clipboard.length(); } }else{ if (head == text.length()){ text += clipboard; }else if (head == 0){ text = clipboard + text; }else{ text = text.substring(0, head) + clipboard + text.substring(insert ? head + 1 : head, text.length()); } draggedFrom = head; head += clipboard.length(); } }catch (Exception exc){ } } }else if (e.isControlDown() &amp;&amp; e.getKeyCode() == KeyEvent.VK_X){ if (draggedFrom != head){ Clipboard board = Toolkit.getDefaultToolkit().getSystemClipboard(); board.setContents(new StringSelection(draggedFrom &lt; head ? text.substring(draggedFrom, head) : text.substring(head, draggedFrom)), this); if (head &lt;= draggedFrom){ text = text.substring(0, head) + text.substring(draggedFrom); }else{ text = text.substring(0, draggedFrom) + text.substring(head); head = draggedFrom; } draggedFrom = head; } }else if (e.getKeyCode() == KeyEvent.VK_DELETE){ if (text.length() &gt; 0){ if (draggedFrom != head){ if (head &lt;= draggedFrom){ text = text.substring(0, head) + text.substring(draggedFrom); }else{ text = text.substring(0, draggedFrom) + text.substring(head); head = draggedFrom; } }else if (head == 0){ text = text.substring(1); }else if (head != text.length()){ text = text.substring(0, head) + text.substring(head + 1); } this.draggedFrom = head; } }else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE){ if (draggedFrom != head){ if (head &lt;= draggedFrom){ text = text.substring(0, head) + text.substring(draggedFrom); }else{ text = text.substring(0, draggedFrom) + text.substring(head); head = draggedFrom; } }else if (head &gt; 0){ head--; if (head == text.length()){ text = text.substring(0, head); }else{ text = text.substring(0, head) + text.substring(head + 1, text.length()); } } this.draggedFrom = head; }else if (e.getKeyCode() != KeyEvent.VK_SHIFT &amp;&amp; e.getKeyCode() != KeyEvent.VK_CONTROL &amp;&amp; e.getKeyCode() != KeyEvent.VK_ALT &amp;&amp; e.getKeyCode() != 12 &amp;&amp; e.getKeyCode() != KeyEvent.VK_ESCAPE &amp;&amp; !e.isActionKey()){ if (draggedFrom != head){ if (head &lt;= draggedFrom){ text = text.substring(0, head) + e.getKeyChar() + text.substring(draggedFrom); head++; }else{ text = text.substring(0, draggedFrom) + e.getKeyChar() + text.substring(head); head = draggedFrom + 1; } }else{ if (head == text.length()){ text += e.getKeyChar(); }else if (head == 0){ text = e.getKeyChar() + (insert ? text.substring(1) : text); }else{ text = text.substring(0, head) + e.getKeyChar() + text.substring(insert ? head + 1 : head, text.length()); } head++; } this.draggedFrom = head; } this.repaint(); } } public void setEditable(boolean editable) { if (this.editable != editable){ this.editable = editable; this.repaint(); } } public String getText() { return text; } public void setText(String text) { if (!this.text.equals(text == null ? "" : text)){ this.text = text == null ? "" : text; this.draggedFrom = this.head = this.text.length(); history.clear(); historyIndex = 0; this.repaint(); } } @Override public void mouseMoved(MouseEvent e) { if (this.getCursor() != Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)){ this.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); } } @Override public void mousePressed(MouseEvent e) { time = -1; renderHead = true; draggedFrom = head = this.getHead(e.getX()); if (doubleClickTimer != -1){ doubleClickTimer = -1; if (head == text.length()){ draggedFrom = 0; }else if (head &gt; 0 &amp;&amp; this.isSplitCharacter(text.charAt(head - 1))){ draggedFrom--; }else if (head == 0){ while (draggedFrom &lt; text.length() &amp;&amp; !this.isSplitCharacter(text.charAt(draggedFrom))){ draggedFrom++; } }else{ while (head &lt; text.length() &amp;&amp; !this.isSplitCharacter(text.charAt(head))){ head++; } while (draggedFrom &gt; 0 &amp;&amp; !this.isSplitCharacter(text.charAt(draggedFrom - 1))){ draggedFrom--; } } }else{ doubleClickTimer = 0; } this.repaint(); this.requestFocusInWindow(); } private boolean isSplitCharacter (char c){ final String splitCharacters = "!@#$%^&amp;*()\\/?&lt;&gt;:;\"\'}{[]`~,.-=+| "; for (char a : splitCharacters.toCharArray()){ if (a == c) return true; } return false; } @Override public void mouseReleased(MouseEvent e) { dragging = false; } @Override public void setFont(Font font) { super.setFont(font); this.repaint(); } @Override public void mouseDragged(MouseEvent e) { doubleClickTimer = -1; dragging = true; int newPlace = this.getHead(e.getX()); if (head != newPlace){ head = newPlace; this.repaint(); } } private int getHead(int x){ x += renderOffset - 7; if (text.length() != 0){ for (int i = 1; i &lt;= text.length(); i++){ if (x &lt;= this.getFontMetrics(this.getFont()).stringWidth(text.substring(0, i)) - this.getFontMetrics(this.getFont()).stringWidth(text.substring(i - 1, i)) / 2){ return i - 1; } } } return text.length(); } public void addActionListener(ActionListener e) { this.listenerList.add(ActionListener.class, e); } public void removeActionListener(ActionListener e){ this.listenerList.remove(ActionListener.class, e); } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void lostOwnership(Clipboard clipboard, Transferable contents) {} @Override public void focusGained(FocusEvent e) { this.renderHead = true; this.time = 0; focus = true; new Thread(this).start(); repaint(); } @Override public void focusLost(FocusEvent e) { this.renderHead = false; this.time = 0; focus = false; repaint(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload