首页 > 解决方案 > 如何通过按键盘上的左右箭头键来更改背景颜色?(不在钟内,在钟外)

问题描述

我对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
        }
    }
}

从现在开始感谢您的答案。正如我所说,我想改变背景,而不是时钟内部的颜色。

标签: javaswing

解决方案


我想通过使用第二类来更改背景颜色。

这不是 Swing 的工作方式。KeyEvents 仅被分派给具有焦点的组件。

你打算用你的 ChangeColor 类做什么?你不能把它放到框架上,因为它什么都不做。

相反,您需要的只是 DirectionListener 类。它应该是时钟类的一部分。然后在 Clock 类的构造函数中创建 DirectionListener 类的实例并将其作为 KeyListener 添加到 Clock 类。

其他问题:

  1. 不要覆盖paint()。相反,当使用 Swing 时,您会覆盖paintComponent(...)。

  2. 不要覆盖更新()。摆脱使用 AWT 完成的代码,而在使用 Swing 时不需要

阅读 Swing 教程中关于自定义绘画的部分以获取更多信息。

首先进行上述更改以清理绘画逻辑。

然后您可以执行以下操作以更好地实施 Swing 编码实践:

  1. 不要使用线程。Swing 组件的更新应该在事件调度线程 (EDT) 上完成。相反,您应该使用Swing Timer

  2. 不要使用 KeyListener。相反,您应该使用Key Bindings

我建议您保留指向 Swing 教程的链接。我提供了 3 个部分的链接。您的大部分代码似乎都基于旧的 AWT 编码实践。将Swing tutorial用作 Swing 的参考。

此外,您还有每个秒、分钟和小时值的变量。所以使用它们。不要一直调用该方法。它使您的代码令人困惑,因为人们会想知道为什么您创建变量并且从不使用它。

事实上,为什么上述每个方法都有多个变量。每个值应该只有一个变量。

作为提示,您可以使用:

    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

在您的绘画方法开始时。它会让你的圆圈更平滑。

查看:拖动绘制的形状作为实施绘制建议的示例。在该示例中,它向面板添加了一个 MouseListener。您想从 KeyListener 开始,但如何实现该类的概念将是相同的。


推荐阅读