我正试图按左右键移动一个点。 这是我的主要内容:
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setSize(500,500);
Graphic graphic=new Graphic();
frame.add(graphic);
}}
这是我创建点的图形类,我实现了KeyListener和ActionListener:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Graphic extends JPanel implements ActionListener, KeyListener {
private int posX = 220;
private int posY = 300;
private Timer timer;
private int delay = 8;
private int width = 500;
private int height = 500;
public Graphic() {
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer = new Timer(delay, this);
timer.start();
this.setSize(width, height);
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, width, height);
g.setColor(Color.GREEN);
g.fillOval(posX, posY, 20, 20);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (posX <= 20) {
posX = 20;
} else {
moveLeft();
}
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (posX >= 460) {
posX = 460;
} else {
moveRight();
}
}
repaint();
}
private void moveRight() {
posX += 20;
}
private void moveLeft() {
posX -= 20;
}
@Override
public void actionPerformed(ActionEvent e) {
timer.start();
repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
在我看来,这应该有用......但事实并非如此。当我按下左右键时没有任何反应,看起来它并没有“听”我的命令。那么,我的代码出了什么问题?
答案 0 :(得分:1)
BEGIN /*PREPARE SAMPLE DATA*/
CREATE TABLE #priceSchedules(
RoomId int not null,
[Date] date not null,
Quota int not null,
Price decimal(18,4) not null
)
INSERT INTO #priceSchedules
select
RoomId = R.RoomId
,[Date] = D.[Date]
,Quota = abs(checksum(NewId()) % 5)
,Price = abs(checksum(NewId()) % 50)
from
(
select top 100
RoomId = row_number() over(order by R.number)
from master..spt_values R
) R
OUTER apply(
select top 60
[Date] = cast(DATEADD(day, row_number() over(order by t1.number), getdate()) as date)
from master..spt_values t1
) D
END
BEGIN /*PARAMETERS*/
DECLARE @RoomId int = 5,
@CheckIn date = cast(dateadd(day, 3, getdate()) as date),
@CheckOut date = cast(dateadd(day, 6, getdate()) as date);
DECLARE @TotalNight int = datediff(day, @CheckIn, @CheckOut)
END
BEGIN /*QUERY */
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS TIME ON; --FOR CHECK PERFORMANCE
PRINT('-----------START SELECT---------------------------------')
SELECT
*
FROM
(
SELECT
_P.*
,RowNo = ROW_NUMBER() OVER(PARTITION BY RoomId ORDER BY DayDiffFromCheckIn)
FROM(
SELECT
P.RoomId
,StartDate = P.[Date]
,EndDate = MAX(P2.[Date])
,CalcDay = COUNT(*)
,DayDiffFromCheckIn = CAST(ABS(DATEDIFF(day,P.[Date],@CheckIn)) AS INT)
,MinQuota = IIF(MIN(P.Quota) > MIN(P2.Quota) ,MIN(P2.Quota),MIN(P.Quota))
,TotalPrice = MIN(P.Price) + SUM(P2.Price)
FROM #priceSchedules P
JOIN #priceSchedules AS P2 ON P2.RoomId = P.RoomId AND P2.[Date] > P.[Date] AND P2.[Date] < DATEADD(day, @TotalNight ,P.[Date]) AND P2.Quota > 0
WHERE P.RoomId = @RoomId AND P.Quota > 0 AND P.[Date] >= GETDATE()
GROUP BY P.RoomId,P.[Date]
HAVING(COUNT(*) = (@TotalNight) - 1) -- -1 is for first row
) _P
)__P
WHERE __P.RowNo < 3 -- for top 3 option colsest to @CheckIn date
PRINT('-----------END SELECT---------------------------------')
--SELECT * FROM #priceSchedules
DROP TABLE #priceSchedules
SET STATISTICS TIME OFF;
END
有效。
当您显示JFrame时,JFrame默认为焦点而不是JPanel。
在KeyListener
构造函数中,只需添加Graphic
:
grabFocus()
修改强>
我已在我的机器上测试过了。问题是它是随机工作的,因为如果我们希望JPanel抓住焦点,JFrame需要可见。有时它是,有时则不是。
public Graphic() {
addKeyListener(this);
setFocusTraversalKeysEnabled(true);
setFocusable(true);
grabFocus();
timer = new Timer(delay, this);
timer.start();
this.setSize(width, height);
}
可以解决问题。
将面板添加到SwingUtilities.invokeLater()
后,调用以JFrame
方法抓取焦点的代码。
invokeLater()
答案 1 :(得分:0)
您拨打repaint
课程的Component
方法,而不是paint
方法。