#java #swing #user-interface #graphics #keylistener
#java #качать #пользовательский интерфейс #графика #Keylistener
Вопрос:
Все в коде работает, за исключением случаев, когда я пытаюсь использовать клавиши для перемещения круга. Я ввел System.out.println(«Работает»), чтобы проверить, работал ли прослушиватель при нажатии любой клавиши, но он вообще не работает. Я сделал то же самое с прослушивателем мыши, и он работал нормально. Я очень новичок в программировании, и я не совсем уверен, что я делаю, поэтому любая помощь была бы отличной.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*; // to use listener interfaces
import java.awt.geom.Ellipse2D;
public class WholePanel extends JPanel
{
private Color foregroundColor, backgroundColor;
private int currentDiameter, x1, y1;
private CanvasPanel canvas;
private JPanel buttonPanel;
private JRadioButton filledRadio, unfilledRadio;
private JRadioButton red, green, blue;
private JRadioButton cyan, yellow, pink;
private JLabel fill, foreColor, backColor;
private ButtonGroup circleColor, canvasColor, circleFill;
public boolean filled = false;
public WholePanel()
{
backgroundColor = Color.CYAN;
foregroundColor = Color.RED;
currentDiameter = 100;
x1 = 200; y1 = 100;
//INITIATING VARIABLES
unfilledRadio = new JRadioButton("Unfilled", true);
filledRadio = new JRadioButton("Filled");
red = new JRadioButton("Red", true);
green = new JRadioButton("Green");
blue = new JRadioButton("Blue");
cyan = new JRadioButton("Cyan", true);
yellow = new JRadioButton("Yellow");
pink = new JRadioButton("Pink");
fill = new JLabel("Circle Filling");
foreColor = new JLabel("Foreground Color");
backColor = new JLabel("Background Color");
//ORGANIZING THE BUTTONS AND LABELS ON THE BUTTON PANEL
buttonPanel = new JPanel(new GridLayout(3,4));
buttonPanel.add(foreColor);
buttonPanel.add(red);
buttonPanel.add(green);
buttonPanel.add(blue);
buttonPanel.add(backColor);
buttonPanel.add(cyan);
buttonPanel.add(yellow);
buttonPanel.add(pink);
buttonPanel.add(fill);
buttonPanel.add(unfilledRadio);
buttonPanel.add(filledRadio);
//BUTTON GROUPS ALLOW FOR ONE RADIO BUTTON SELECTION AT A TIME
circleColor = new ButtonGroup();
circleColor.add(red);
circleColor.add(green);
circleColor.add(blue);
canvasColor = new ButtonGroup();
canvasColor.add(cyan);
canvasColor.add(yellow);
canvasColor.add(pink);
circleFill = new ButtonGroup();
circleFill.add(unfilledRadio);
circleFill.add(filledRadio);
//MAKES LISTENER FOR ALL RADIO BUTTONS
FillListener listener1 = new FillListener();
unfilledRadio.addActionListener(listener1);
filledRadio.addActionListener(listener1);
ColorListener listener2 = new ColorListener();
red.addActionListener(listener2);
green.addActionListener(listener2);
blue.addActionListener(listener2);
cyan.addActionListener(listener2);
yellow.addActionListener(listener2);
pink.addActionListener(listener2);
canvas = new CanvasPanel();
JSplitPane sPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, buttonPanel, canvas);
setLayout(new BorderLayout());
add(sPane, BorderLayout.CENTER);
}
//Its description should be completed
private class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//CHANGES COLOR BASED ON WHICH BUTTON IS SELECTED
if(event.getSource() == cyan)
{
backgroundColor = Color.CYAN;
}
else if(event.getSource() == yellow)
{
backgroundColor = Color.YELLOW;
}
else if(event.getSource() == pink)
{
backgroundColor = Color.PINK;
}
if(event.getSource() == red)
{
foregroundColor = Color.RED;
}
else if(event.getSource() == green)
{
foregroundColor = Color.GREEN;
}
else if(event.getSource() == blue)
{
foregroundColor = Color.BLUE;
}
//SETS THE COLORS
setBackground(backgroundColor);
setForeground(foregroundColor);
}
} // end of ColorListener
//Its description should be completed
private class FillListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
//CHECKS IF USER WANTS CIRCLE FILLED OR UNFILLED
if(event.getSource() == unfilledRadio)
{
filled = false;
}
if(event.getSource() == filledRadio)
{
filled = true;
}
}
}
//CanvasPanel is the panel where a circle is drawn
private class CanvasPanel extends JPanel
{
//Constructor to initialize the canvas panel
public CanvasPanel( )
{
// make this canvas panel listen to keys
addKeyListener(new DirectionListener());
// make this canvas panel listen to mouse
addMouseListener(new PointListener());
setBackground(backgroundColor);
setForeground(foregroundColor);
//This method needs to be called for this panel to listen to keys
//When panel listens to other things, and go back to listen
//to keys, this method needs to be called again.
requestFocus();
}
//this method draws all characters pressed by a user so far
public void paintComponent(Graphics page)
{
super.paintComponent(page);
//SETS THE COLORS BASED ON USERS CHOICE
setBackground(backgroundColor);
setForeground(foregroundColor);
//DRAWS THE CIRCLE
Graphics2D page2d = (Graphics2D)page;
//DRAWS IT FILLED OR UNFILLED BASED ON USER CHOICE
if(filled == true)
{
page.setColor(foregroundColor);
Ellipse2D.Double circle = new Ellipse2D.Double(x1,y1,currentDiameter,currentDiameter);
page2d.fill(circle);
canvas.repaint();
}
else if(filled == false)
{
page.setColor(foregroundColor);
Ellipse2D.Double circle = new Ellipse2D.Double(x1,y1,currentDiameter,currentDiameter);
page2d.draw(circle);
canvas.repaint();
}
}
/** This method is overridden to enable keyboard focus */
public boolean isFocusable()
{
return true;
}
// listener class to listen to keyboard keys
private class DirectionListener implements KeyListener
{
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
// in case that a key is pressed, the following will be executed.
public void keyPressed(KeyEvent e)
{
//FOCUSES THE LISTENER ON THE KEYBOARD
canvas.requestFocus();
//CHANGES THE SIZE/POSITION OF CIRCLE IF KEYS ARE PRESSED
if(e.getKeyChar() == KeyEvent.VK_UP)
{
y1 = y1 5;
canvas.repaint();
}
else if(e.getKeyChar() == KeyEvent.VK_DOWN)
{
y1 = y1-5;
canvas.repaint();
}
else if(e.getKeyChar() == KeyEvent.VK_RIGHT)
{
x1 = x1 5;
canvas.repaint();
}
else if(e.getKeyChar() == KeyEvent.VK_LEFT)
{
x1 = x1-5;
canvas.repaint();
}
else if(e.getKeyChar() == 's')
{
if(currentDiameter >= 16)
currentDiameter = currentDiameter - 6;
canvas.repaint();
}
else if(e.getKeyChar() == 'b')
{
currentDiameter = currentDiameter 6;
canvas.repaint();
}
}
} // end of DirectionListener
// listener class that listens to the mouse
// This class is already completed. No adjustment is needed.
public class PointListener implements MouseListener
{
//in case that a user presses using a mouse,
//it gains the focus of the keyboard keys
public void mousePressed (MouseEvent event)
{
canvas.requestFocus();
}
public void mouseClicked (MouseEvent event) {}
public void mouseReleased (MouseEvent event) {}
public void mouseEntered (MouseEvent event) {}
public void mouseExited (MouseEvent event) {}
} // end of PointListener
} // end of Canvas Panel Class
} // end of Whole Panel Class
Ответ №1:
Ключевые события отправляются только компоненту с фокусом. По умолчанию панель не фокусируется.
Вам нужно добавить:
setFocusable(true);
в конструкторе вашего класса.
Вы можете запросить фокус только на видимом компоненте, что означает, что оператор requestFocust() в конструкторе ничего не сделает. Кроме того, метод, который нужно использовать requestFocusInWindow()
(снова после того, как фрейм виден).
Наконец, вы должны использовать привязки клавиш для прослушивания ключевых событий в компоненте (поэтому вам не нужно беспокоиться о том, что компонент имеет фокус). Дополнительную информацию и примеры см. в разделе Движение с помощью клавиатуры.