在Java中调用repaint()时如何避免闪烁?
我已经看过许多类似问题的答案,但它们似乎都在说我在做一个JPanel,所以我不知道如何使我的矩形不闪烁 我正在制作一个屏幕截图,就像Mac电脑上的CMD+SHIFT+4功能一样。我让所有东西都工作了,也就是说,当你拖动一个矩形时,它会拍照,但是你选择的矩形会一直闪烁在Java中调用repaint()时如何避免闪烁?,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我已经看过许多类似问题的答案,但它们似乎都在说我在做一个JPanel,所以我不知道如何使我的矩形不闪烁 我正在制作一个屏幕截图,就像Mac电脑上的CMD+SHIFT+4功能一样。我让所有东西都工作了,也就是说,当你拖动一个矩形时,它会拍照,但是你选择的矩形会一直闪烁 import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.KeyE
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.File;
import java.io.PrintWriter;
import javax.swing.*;
import javax.swing.event.*;
import javax.imageio.ImageIO;
import java.text.SimpleDateFormat;
import java.util.*;
import java.awt.geom.Area;
public class ScreenShotter extends JPanel implements MouseListener {
static JPanel contentPane;
private static JPanel picture1;
static int startX, startY, endX, endY;
static int width;
static int height;
int x, y;
int radius = 2;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd kk.mm.ss");
static File f = new File("ScreenShotter.txt");
static String filePath = f.getPath();
static String screenshotPath = "";
JFileChooser chooser;
String chooserTitle = "Select the folder to store your screenshots";
static Point currentPoint;
static Point startPoint;
static boolean clicked = false;
static BufferStrategy bs;
public ScreenShotter() {
setLayout(new BorderLayout());
contentPane = new JPanel(new BorderLayout());
contentPane.requestFocus();
picture1 = new JPanel();
picture1.addMouseListener(this);
picture1.setPreferredSize(new Dimension(width, height));
contentPane.add(picture1);
}
public ScreenShotter(boolean bool){
final String[] labels = {"Screen width: ", "Screen Height: "};
int labelsLength = labels.length;
final JTextField[] textField = new JTextField[labelsLength];
final JPanel p = new JPanel(new SpringLayout());
for(int i = 0; i < labelsLength; i++){
JLabel l = new JLabel(labels[i], JLabel.TRAILING);
p.add(l);
textField[i] = new JTextField(10);
l.setLabelFor(textField[i]);
p.add(textField[i]);
}
final JButton button = new JButton("Submit");
p.add(new JLabel());
p.add(button);
SpringUtilities.makeCompactGrid(p,
labelsLength + 1, 2,
7, 7,
7, 7);
final JFrame frame = new JFrame("File Maker");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//for(int i = 0; i < labels.length; i++){
//System.out.println(labels[i]+"->"+textField[i].getText());
//screenshotPath = textField[0].getText();
width = Integer.parseInt(textField[0].getText());
height = Integer.parseInt(textField[1].getText());
//}
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
chooser.setDialogTitle(chooserTitle);
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if(chooser.showOpenDialog(button) == JFileChooser.APPROVE_OPTION){
System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory());
System.out.println("getSelectedFile(): " + chooser.getSelectedFile());
screenshotPath = slashConverter(chooser.getSelectedFile().toString());
} else {
System.out.println("No selection.");
}
frame.dispose();
createFile();
}
});
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
p.setOpaque(true);
frame.setContentPane(p);
frame.pack();
frame.setSize(210, 123);
frame.setResizable(false);
frame.setVisible(true);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(210, 123);
}
public static void main(String[] args){
try {UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName());}
catch (UnsupportedLookAndFeelException e) {}
catch (ClassNotFoundException e) {}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}
if(f.exists()){
width = getWidthFromFile(filePath);
height = getHeightFromFile(filePath);
startScreenShotter();
}
if(!f.exists()){
JFrame fileMaker = new JFrame("File Maker");
fileMaker.add(new ScreenShotter(true));
}
}
public static void startScreenShotter(){
JFrame frame = new JFrame("ScreenShotter");
frame.add(new ScreenShotter());
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setOpacity(0.33f);
frame.setContentPane(contentPane);
frame.setVisible(true);
frame.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent ke) {
if(ke.getKeyCode() == ke.VK_ESCAPE){
System.exit(0);
}
}
public void keyReleased(KeyEvent ke) {}
public void keyTyped(KeyEvent ke) {}
});
while(true){
currentPoint = MouseInfo.getPointerInfo().getLocation();
if(currentPoint != startPoint && clicked){
drawRectangle(startPoint, currentPoint, picture1);
}
//System.out.println(currentPoint);
//delay(1);
}
}
public static void drawRectangle(Point start, Point current, Object source){
if(source instanceof JPanel){
picture1.repaint();
//delay(1);
Rectangle r = new Rectangle(rectChecker(start.x, start.y, current.x, current.y));
Graphics g = ((JComponent) source).getGraphics();
g.fillRect((int)r.getX(), (int)r.getY(), (int)r.getWidth(), (int)r.getHeight());
g.setColor(new Color(255, 255, 255, 50));
//delay(1);
}
}
public static void delay(int time){
try{
Thread.sleep(time);
} catch(InterruptedException e){
System.out.println("wot");
}
}
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
//drawCircle(e.getX()-(radius/2), e.getY()-(radius/2), e.getSource(), true);
//repaint();
startX = x;
startY = y;
startPoint = new Point(startX, startY);
clicked = true;
//System.out.println("(" + startX + ", " + startY + ")");
}
public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
//drawCircle(e.getX()-(radius/2), e.getY()-(radius/2), e.getSource(), true);
//repaint();
endX = x;
endY = y;
//System.out.println("(" + endX + ", " + endY + ")");
Frame[] f = Frame.getFrames();
for(int i = 0; i < f.length; i++){
f[i].dispose();
}
try {
robo(rectChecker(startX, startY, endX, endY));
System.exit(0);
} catch(Exception ex){
System.exit(1);
}
}/*
public void drawCircle(int x, int y, Object source, boolean fill) {
if(source instanceof JPanel) {
Graphics g = ((JComponent) source).getGraphics();
g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
g.setColor(Color.RED);
if (fill) {
g.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
}
} // else ignore
}*/
public void robo(Rectangle r) throws Exception{
Calendar now = Calendar.getInstance();
Robot robot = new Robot();
BufferedImage screenshot = robot.createScreenCapture(r);
ImageIO.write(screenshot, "PNG", new File(getPath(filePath) + "Screenshot "+formatter.format(now.getTime())+".png"));
}
public static String getPath(String file){
if(f.exists()){
try(BufferedReader br = new BufferedReader(new FileReader(file))){
String sCurrentLine;
while((sCurrentLine = br.readLine()) != null){
return sCurrentLine;
}
} catch(IOException e){
e.printStackTrace();
}
return null;
}
return null;
}
public static int getWidthFromFile(String file){
if(f.exists()){
try(BufferedReader br = new BufferedReader(new FileReader(file))){
br.readLine();
int width = Integer.parseInt(br.readLine());
return width;
} catch(IOException e){
e.printStackTrace();
}
}
return 0;
}
public static int getHeightFromFile(String file){
if(f.exists()){
try(BufferedReader br = new BufferedReader(new FileReader(file))){
br.readLine();
br.readLine();
int height = Integer.parseInt(br.readLine());
return height;
} catch(IOException e){
e.printStackTrace();
}
}
return 0;
}
public static Rectangle rectChecker(int x0, int y0, int x1, int y1){
if(x0 > x1 && y0 < y1){
int x = x1;
int y = y0;
int width = x0 - x1;
int height = y1 - y0;
Rectangle r = new Rectangle(x, y, width, height);
return r;
}
if(x0 < x1 && y0 > y1){
int x = x0;
int y = y1;
int width = x1 - x0;
int height = y0 - y1;
Rectangle r = new Rectangle(x, y, width, height);
return r;
}
if(x0 > x1 && y0 > y1){
int x = x1;
int y = y1;
int width = x0 - x1;
int height = y0 - y1;
Rectangle r = new Rectangle(x, y, width, height);
return r;
}
int x = x0;
int y = y0;
int width = x1 - x0;
int height = y1 - y0;
Rectangle r = new Rectangle(x, y, width, height);
return r;
}
public static void createFile(){
System.out.println(width + " " + height + " " + filePath);
try(PrintWriter writer = new PrintWriter(filePath, "UTF-8")){
writer.println(screenshotPath);
writer.println(width);
writer.println(height);
writer.close();
} catch(IOException ioe){
System.out.println("Call a doctor!");
}
startScreenShotter();
}
public static String slashConverter(String str){
if(str.contains("\\")){
str = str.replace("\\", "/");
if(str.charAt(str.length()-1) != '/'){
str = str + "/";
}
return str;
}
return str;
}
//public void mousePressed(MouseEvent e) {}
//public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
import java.awt.*;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.awt.image.BufferStrategy;
导入java.io.FileReader;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.File;
导入java.io.PrintWriter;
导入javax.swing.*;
导入javax.swing.event.*;
导入javax.imageio.imageio;
导入java.text.simpleDataFormat;
导入java.util.*;
导入java.awt.geom.Area;
公共类ScreenShotter扩展JPanel实现MouseListener{
静态JPanel内容窗格;
私有静态JPanel图片1;
静态整数startX、startY、endX、endY;
静态整数宽度;
静态内高度;
int x,y;
int半径=2;
SimpleDataFormat格式化程序=新的SimpleDataFormat(“yyyy-MM-dd kk.MM.ss”);
静态文件f=新文件(“ScreenShotter.txt”);
静态字符串filePath=f.getPath();
静态字符串screenshotPath=“”;
JFileChooser选择器;
String chooserTitle=“选择用于存储屏幕截图的文件夹”;
静态点电流点;
静态点起始点;
静态布尔值=false;
静态缓冲策略;
公众截屏者(){
setLayout(新的BorderLayout());
contentPane=newjpanel(newborderlayout());
contentPane.requestFocus();
picture1=新JPanel();
图1.addMouseListener(本);
图1.设置首选尺寸(新尺寸(宽度、高度));
contentPane.add(图1);
}
公共屏幕截图(布尔布尔布尔){
最终字符串[]标签={“屏幕宽度:”,“屏幕高度:”};
int labelsLength=labels.length;
最终JTextField[]textField=新JTextField[标签长度];
final JPanel p=newjpanel(newspringlayout());
for(int i=0;i”+textField[i].getText());
//screenshotPath=textField[0]。getText();
width=Integer.parseInt(textField[0].getText());
height=Integer.parseInt(textField[1].getText());
//}
chooser=newjfilechooser();
chooser.setCurrentDirectory(新文件(“.”);
选择器.setDialogTitle(选择器标题);
setFileSelectionMode(仅限于JFileChooser.DIRECTORIES_);
选择器.setAcceptableFileFilterUsed(false);
if(chooser.showOpenDialog(按钮)=JFileChooser.APPROVE\u选项){
System.out.println(“getCurrentDirectory():”+chooser.getCurrentDirectory());
System.out.println(“getSelectedFile():”+chooser.getSelectedFile());
screenshotPath=slashConverter(chooser.getSelectedFile().toString());
}否则{
System.out.println(“无选择”);
}
frame.dispose();
createFile();
}
});
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
p、 set不透明(true);
frame.setContentPane(p);
frame.pack();
帧设置大小(210123);
frame.setresizeable(false);
frame.setVisible(true);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(210123);
}
公共静态void main(字符串[]args){
请尝试{UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
捕获(无支持的LookandFeelexception e){}
catch(classnotfound异常){}
catch(实例化异常e){}
捕获(非法访问例外){}
如果(f.exists()){
宽度=getWidthFromFile(文件路径);
高度=getHeightFromFile(文件路径);
startScreenShotter();
}
如果(!f.exists()){
JFrame fileMaker=新的JFrame(“文件生成器”);
添加(新屏幕快照(true));
}
}
公共静态void startScreenShotter(){
JFrame=新的JFrame(“屏幕快照”);
frame.add(新的ScreenShotter());
框架尺寸(宽度、高度);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架。设置未装饰(真实);
帧不透明度(0.33f);
frame.setContentPane(contentPane);
frame.setVisible(true);
frame.addKeyListener(新的KeyListener(){
按下公共无效键(KeyEvent ke){
if(ke.getKeyCode()==ke.VK_ESCAPE){
系统出口(0);
}
}
public void keyreased(KeyEvent ke){}
public void keyTyped(KeyEvent ke){}
});
while(true){
currentPoint=MouseInfo.getPointerInfo().getLocation();
if(currentPoint!=开始点&&clicked){
绘图矩形(起点、当前点、图片1);
}
//系统输出打印项次(currentPoint);
//延迟(1);
}
}
公共静态void drawRectangle(点起点、点当前、对象源){
if(JPanel的源实例){
图1.重新绘制();
//延迟(1);
矩形
Graphics g = ((JComponent) source).getGraphics();
while (true) {
currentPoint = MouseInfo.getPointerInfo().getLocation();
if (currentPoint != startPoint && clicked) {
drawRectangle(startPoint, currentPoint, picture1);
}
//System.out.println(currentPoint);
//delay(1);
}