java - 如何通过按键盘上的左右箭头键来更改背景颜色?(不在钟内,在钟外)
问题描述
我对Java编程很陌生,我主要从互联网上找到了这段代码,但对其进行了一些编辑。我认为代码工作正常。它正确显示当前时间和指针变化。我想通过使用第二类来更改背景颜色。
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Clock extends JPanel implements Runnable {
Thread thread = null;
int xcenter = 175;
int ycenter = 175;
private void drawStructure(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g.setFont(new Font("Italic", Font.ITALIC, 25));
g.setColor(Color.LIGHT_GRAY);
g2.setStroke(new BasicStroke(20));
g.drawOval(xcenter- 150, ycenter - 150, 300, 300);
g.setColor(Color.BLACK);
g.fillOval(xcenter-150, ycenter-150,300, 300);
g.setColor(Color.RED);
g.drawString("9",xcenter- 145, ycenter + 0);
g.drawString("3",xcenter + 135, ycenter + 0);
g.drawString("12",xcenter - 10, ycenter - 130);
g.drawString("6", xcenter- 10, ycenter + 145);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
drawStructure(g);
LocalDateTime now = LocalDateTime.now();
int xksaniye = now.getSecond();
int yksaniye = now.getSecond();
int xkdakika = now.getMinute();
int ykdakika = now.getMinute();
int xksaat = now.getHour();
int yksaat = now.getHour();
xksaniye = (int) (Math.cos(now.getSecond() * 3.14f / 30 - 3.14f / 2) * 120 + xcenter);
yksaniye = (int)(Math.sin(now.getSecond() * 3.14f / 30 - 3.14f / 2) * 120 + ycenter);
xkdakika = (int)(Math.cos(now.getMinute() * 3.14f / 30 - 3.14f / 2) * 100 + xcenter);
ykdakika = (int)(Math.sin(now.getMinute() * 3.14f / 30 - 3.14f / 2) * 100 + ycenter);
xksaat = (int)(Math.cos((now.getHour() * 30 + now.getMinute() / 2) * 3.14f / 180 - 3.14f / 2) * 80 + xcenter);
yksaat = (int)(Math.sin(( now.getHour() * 30 + now.getMinute() / 2) * 3.14f / 180 - 3.14f / 2) * 80 + ycenter);
g.setColor(Color.magenta);
g2.setStroke(new BasicStroke(5));
g.drawLine(xcenter, ycenter,xksaniye, yksaniye);
g.setColor(Color.red);
g2.setStroke(new BasicStroke(5));
g.drawLine(xcenter, ycenter - 1,xkdakika, ykdakika);
g.drawLine(xcenter - 1, ycenter, xkdakika,ykdakika);
g.setColor(Color.green);
g2.setStroke(new BasicStroke(5));
g.drawLine(xcenter, ycenter - 1, xksaat, yksaat);
g.drawLine(xcenter - 1, ycenter,xksaat,yksaat);
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
while (thread != null) {
try {
Thread.sleep(100);
}
catch (InterruptedException e) {}
repaint();
}
thread = null;
}
public void update(Graphics g){
paint(g);
}
public static void main(String[] args){
JFrame f = new JFrame("Analog Saat Pojesi");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Clock());
f.setBounds(0, 0, 370, 400);
Clock clock = new Clock();
f.add(clock);
f.setLocationRelativeTo(null);
f.setVisible(true);
clock.start();
Clock saat = new Clock();
}
}
你在这里看到我的第二节课。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChangeColor extends JPanel{
public ChangeColor(){
addKeyListener(new DirectionListener());
setFocusable(true);
setBackground(Color.yellow);
}
private class DirectionListener implements KeyListener{
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT){
setBackground(Color.red);
}
repaint();
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
从现在开始感谢您的答案。正如我所说,我想改变背景,而不是时钟内部的颜色。
解决方案
我想通过使用第二类来更改背景颜色。
这不是 Swing 的工作方式。KeyEvents 仅被分派给具有焦点的组件。
你打算用你的 ChangeColor 类做什么?你不能把它放到框架上,因为它什么都不做。
相反,您需要的只是 DirectionListener 类。它应该是时钟类的一部分。然后在 Clock 类的构造函数中创建 DirectionListener 类的实例并将其作为 KeyListener 添加到 Clock 类。
其他问题:
不要覆盖paint()。相反,当使用 Swing 时,您会覆盖paintComponent(...)。
不要覆盖更新()。摆脱使用 AWT 完成的代码,而在使用 Swing 时不需要
阅读 Swing 教程中关于自定义绘画的部分以获取更多信息。
首先进行上述更改以清理绘画逻辑。
然后您可以执行以下操作以更好地实施 Swing 编码实践:
不要使用线程。Swing 组件的更新应该在事件调度线程 (EDT) 上完成。相反,您应该使用Swing Timer
不要使用 KeyListener。相反,您应该使用Key Bindings。
我建议您保留指向 Swing 教程的链接。我提供了 3 个部分的链接。您的大部分代码似乎都基于旧的 AWT 编码实践。将Swing tutorial
用作 Swing 的参考。
此外,您还有每个秒、分钟和小时值的变量。所以使用它们。不要一直调用该方法。它使您的代码令人困惑,因为人们会想知道为什么您创建变量并且从不使用它。
事实上,为什么上述每个方法都有多个变量。每个值应该只有一个变量。
作为提示,您可以使用:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
在您的绘画方法开始时。它会让你的圆圈更平滑。
查看:拖动绘制的形状作为实施绘制建议的示例。在该示例中,它向面板添加了一个 MouseListener。您想从 KeyListener 开始,但如何实现该类的概念将是相同的。
推荐阅读
- ruby-on-rails - 控制器的未定义局部变量或方法“参数”
- javascript - 要单击图像图标,react-datepicker 的输入框不起作用
- continuous-integration - Bitbucket / 我看不到管道中的工件
- java - 如何通过 WiFiP2P 为客户端/服务器调用相同的功能?
- python - python Problem Set 1 Part C 中的 MIT 编程
- html - 当容器 ul 可见时绘制 svg 线条
- c# - 在重定向期间在 RestSharp 中保留授权标头
- eclipse - Eclipse IDE BUG - 优化级别,调试级别弹出到 NONE
- angular - 找不到模块的 NgModule 元数据中的错误('DeviceProfileConfigurationModule')
- java - 如何在 Java 中的网络摄像头上运行训练有素的 Tensorflow 模型