我正在努力用Java制作一个图片浏览器,对于我的生活,我无法将观察者的背景颜色变为黑色。这是我的最新代码:
public class PictureViewer extends JFrame {
static class PauseAction extends AbstractAction {
public void actionPerformed(ActionEvent arg0) {
pauseViewer = !pauseViewer;
}
}
static class QuitAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
stopViewer = true;
pauseViewer = true;
viewer.setNextToView();
System.exit(0);
}
}
static Double height;
static final String newline = System.getProperty("line.separator");
static boolean pauseViewer = false;
static Dimension screensize = new Dimension();
static boolean stopViewer = false;
static PictureViewer viewer;
static Double width;
JLabel area = new JLabel("", JLabel.CENTER);
int currentPic = 0;
File dir = new File(".");
BufferedImage image;
String path;
Action pauseAction;
int pauseTime = 5;
Action quitAction;
private JScrollPane scrollPane = new JScrollPane(area, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
ArrayList<File> thesePictures;
public static void main(String[] args) throws IOException {
//Create and set up the window.
viewer = new PictureViewer();
viewer.setUndecorated(true); //Remove the minimize, maximize and close buttons entirely.
//Get the list of files to display.
viewer.initialize();
//Set up the content pane.
viewer.addComponents();
viewer.setPreferredSize(screensize);
//Display the window.
viewer.pack();
viewer.setVisible(true);
//Start showing pictures.
while (!stopViewer) {
try {
viewer.showPictures();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Perform cleanup
viewer.setNextToView();
}
public void addComponents() {
//Set up actions.
pauseAction = new PauseAction();
quitAction = new QuitAction();
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("P"), "doPauseAction");
scrollPane.getActionMap().put("doPauseAction", pauseAction);
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doQuitAction");
scrollPane.getActionMap().put("doQuitAction", quitAction);
scrollPane.setBackground(Color.BLACK);
getContentPane().add(scrollPane);
viewer.repaint();
}
public ArrayList<File> getPictures(File dir) {
ArrayList<File> listFiles = new ArrayList<File>(Arrays.asList(dir.listFiles()));
int selectThis = (int) (Math.random() * listFiles.size());
boolean emptyList = true;
if (listFiles.get(selectThis).isDirectory()) {
return getPictures(listFiles.get(selectThis));
} else {
//if the selected file is not a directory, go through the list of files and remove any directories.
ArrayList<File> newList = new ArrayList<File>();
for (File thisFile : listFiles) {
if (!thisFile.isDirectory() && !thisFile.getName().contains(".next") && !thisFile.getName().contains(".jar")) {
newList.add(thisFile);
}
}
listFiles = newList;
}
return listFiles;
}
public void initialize() {
screensize = Toolkit.getDefaultToolkit().getScreenSize();
height = screensize.getHeight();
width = screensize.getWidth();
String filePath = new File(".").getAbsolutePath();
filePath = filePath.substring(0, filePath.length() - 1);
String directory = "";
while (thesePictures == null || thesePictures.size() == 0) {
thesePictures = getPictures(dir);
}
String absolutePath = thesePictures.get(0).getAbsolutePath();
path = absolutePath.substring(0,absolutePath.lastIndexOf(File.separator));
//Look to see if the .next file exists. If so, read in the file object. If not, set the index to 0.
File checkFile = new File(path + "\\.next");
if (checkFile.exists()) {
try {
InputStream inputFile = new FileInputStream(path + "\\.next");
InputStream buffer = new BufferedInputStream(inputFile);
ObjectInput input = new ObjectInputStream(buffer);
File lastViewedPic = (File) input.readObject();
if (thesePictures.contains(lastViewedPic)) {
currentPic = thesePictures.indexOf(lastViewedPic);
} else {
currentPic = 0;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Look at " + path + "\\.next");
System.exit(-1);
}
} else {
currentPic = 0;
}
}
public void readInFile(String fileName) {
File file = new File(fileName);
if(file.isFile()) {
try {
image = ImageIO.read(file);
if (image.getWidth() > width || image.getHeight() > height) {
BufferedImage newImage = new BufferedImage(width.intValue(), height.intValue(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, width.intValue(), height.intValue(), null);
g.dispose();
image = newImage;
}
} catch (IOException e) {
showMessageDialog(viewer,"Does not compute !","No file read or found",INFORMATION_MESSAGE);
e.printStackTrace();
} catch (Exception e) {
showMessageDialog(viewer, "Problem: " + e.getLocalizedMessage());
}
}
}
public void setImage(JLabel area){
ImageIcon icon = new ImageIcon(image);
area.setIcon(icon);
viewer.repaint();
}
protected void setNextToView() {
//See if the next picture to view file exists. If not, create it.
File checkFile = new File(path + "\\.next");
if (!checkFile.exists()) {
try {
checkFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
FileOutputStream outputFile = new FileOutputStream(path + "\\.next");
ObjectOutputStream writer = new ObjectOutputStream(outputFile);
writer.writeObject(thesePictures.get(currentPic));
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void showPictures() throws InterruptedException {
while (!pauseViewer) {
//If we reach the last file in the directory, switch to another directory (it could be the same directory).
if (currentPic + 1 == thesePictures.size()) {
currentPic = 0;
thesePictures = new ArrayList<File>();
while (thesePictures == null || thesePictures.size() == 0) {
thesePictures = getPictures(dir);
}
} else {
currentPic += 1;
}
readInFile(thesePictures.get(currentPic).getAbsolutePath());
setImage(area);
TimeUnit.SECONDS.sleep(pauseTime);
}
}
}
我做错了什么?
谢谢!
答案 0 :(得分:4)
尝试设置scrollPane
组件的背景颜色。您将滚动窗格附加到内容窗格,然后设置内容窗格的背景颜色,但滚动窗格覆盖内容窗格,因此您无法看到内容窗格的背景。
修改强>:
我看了你的全班,发现了一个令人困惑的部分。这全部包含在PictureViewer
类中,但您还要访问PictureViewer viewer;
的静态实例。再看一下你的方法:
public void addComponents() {
//Set up actions.
pauseAction = new PauseAction();
quitAction = new QuitAction();
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("P"), "doPauseAction");
scrollPane.getActionMap().put("doPauseAction", pauseAction);
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doQuitAction");
scrollPane.getActionMap().put("doQuitAction", quitAction);
scrollPane.setBackground(Color.BLACK);
getContentPane().add(scrollPane);
viewer.repaint();
}
您已将scrollPane
组件添加到getContentPane().add(scrollPane)
,但对getContentPane()
的调用将返回this
实例的内容窗格,而不是静态{{ 1}}实例。试一试:
viewer
答案 1 :(得分:4)
您只是无缘无故地使用了太多static
个字段,这使您的类不易扩展。此外,PictureViewer
类扩展JFrame
然后在其中,而不是使用相同的引用(您调用getContentPane().add(scrollPane)
之类的方法),而是创建一个新的static
引用使用PictureViewer viewer = new PictureViewer()
,它们如何在同一个实例上。
此外,为了改变JScrollPane
的背景,只需做这件事:
scrollPane.getViewport().setBackground(Color.BLACK);
这是你修改后的代码,虽然我从来没有深入探讨所有不良做法,但我确实设法带来了一些: - )
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class PictureViewer {
class PauseAction extends AbstractAction {
public void actionPerformed(ActionEvent arg0) {
pauseViewer = !pauseViewer;
}
}
class QuitAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
stopViewer = true;
pauseViewer = true;
setNextToView();
System.exit(0);
}
}
static Double height;
static final String newline = System.getProperty("line.separator");
static boolean pauseViewer = false;
static Dimension screensize = new Dimension();
static boolean stopViewer = false;
static JFrame viewer;
static Double width;
JLabel area = new JLabel("", JLabel.CENTER);
int currentPic = 0;
File dir = new File(".");
BufferedImage image;
String path;
Action pauseAction;
int pauseTime = 5;
Action quitAction;
private JScrollPane scrollPane = new JScrollPane(area, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
ArrayList<File> thesePictures;
private void displayGUI() {
//Create and set up the window.
viewer = new JFrame("Picture Viewer");
viewer.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
viewer.setUndecorated(true); //Remove the minimize, maximize and close buttons entirely.
//Get the list of files to display.
initialize();
//Set up the content pane.
addComponents();
viewer.setPreferredSize(screensize);
//Display the window.
viewer.pack();
viewer.setVisible(true);
//Start showing pictures.
while (!stopViewer) {
try {
showPictures();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Perform cleanup
setNextToView();
}
public static void main(String[] args) throws IOException {
Runnable runnable = new Runnable() {
@Override
public void run() {
new PictureViewer().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
public void addComponents() {
//Set up actions.
pauseAction = new PauseAction();
quitAction = new QuitAction();
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("P"), "doPauseAction");
scrollPane.getActionMap().put("doPauseAction", pauseAction);
scrollPane.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doQuitAction");
scrollPane.getActionMap().put("doQuitAction", quitAction);
scrollPane.getViewport().setBackground(Color.BLACK);
viewer.add(scrollPane);
}
public ArrayList<File> getPictures(File dir) {
ArrayList<File> listFiles = new ArrayList<File>(Arrays.asList(dir.listFiles()));
int selectThis = (int) (Math.random() * listFiles.size());
boolean emptyList = true;
if (listFiles.get(selectThis).isDirectory()) {
return getPictures(listFiles.get(selectThis));
} else {
//if the selected file is not a directory, go through the list of files and remove any directories.
ArrayList<File> newList = new ArrayList<File>();
for (File thisFile : listFiles) {
if (!thisFile.isDirectory() && !thisFile.getName().contains(".next") && !thisFile.getName().contains(".jar")) {
newList.add(thisFile);
}
}
listFiles = newList;
}
return listFiles;
}
public void initialize() {
screensize = Toolkit.getDefaultToolkit().getScreenSize();
height = screensize.getHeight();
width = screensize.getWidth();
String filePath = new File(".").getAbsolutePath();
filePath = filePath.substring(0, filePath.length() - 1);
String directory = "";
while (thesePictures == null || thesePictures.size() == 0) {
thesePictures = getPictures(dir);
}
String absolutePath = thesePictures.get(0).getAbsolutePath();
path = absolutePath.substring(0,absolutePath.lastIndexOf(File.separator));
//Look to see if the .next file exists. If so, read in the file object. If not, set the index to 0.
File checkFile = new File(path + "\\.next");
if (checkFile.exists()) {
try {
InputStream inputFile = new FileInputStream(path + "\\.next");
InputStream buffer = new BufferedInputStream(inputFile);
ObjectInput input = new ObjectInputStream(buffer);
File lastViewedPic = (File) input.readObject();
if (thesePictures.contains(lastViewedPic)) {
currentPic = thesePictures.indexOf(lastViewedPic);
} else {
currentPic = 0;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Look at " + path + "\\.next");
System.exit(-1);
}
} else {
currentPic = 0;
}
}
public void readInFile(String fileName) {
File file = new File(fileName);
if(file.isFile()) {
try {
image = ImageIO.read(file);
if (image.getWidth() > width || image.getHeight() > height) {
BufferedImage newImage = new BufferedImage(width.intValue(), height.intValue(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, width.intValue(), height.intValue(), null);
g.dispose();
image = newImage;
}
} catch (IOException e) {
showMessageDialog(viewer,"Does not compute !","No file read or found",INFORMATION_MESSAGE);
e.printStackTrace();
} catch (Exception e) {
showMessageDialog(viewer, "Problem: " + e.getLocalizedMessage());
}
}
}
public void setImage(JLabel area){
ImageIcon icon = new ImageIcon(image);
area.setIcon(icon);
viewer.repaint();
}
protected void setNextToView() {
//See if the next picture to view file exists. If not, create it.
File checkFile = new File(path + "\\.next");
if (!checkFile.exists()) {
try {
checkFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
FileOutputStream outputFile = new FileOutputStream(path + "\\.next");
ObjectOutputStream writer = new ObjectOutputStream(outputFile);
writer.writeObject(thesePictures.get(currentPic));
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void showPictures() throws InterruptedException {
while (!pauseViewer) {
//If we reach the last file in the directory, switch to another directory (it could be the same directory).
if (currentPic + 1 == thesePictures.size()) {
currentPic = 0;
thesePictures = new ArrayList<File>();
while (thesePictures == null || thesePictures.size() == 0) {
thesePictures = getPictures(dir);
}
} else {
currentPic += 1;
}
readInFile(thesePictures.get(currentPic).getAbsolutePath());
setImage(area);
TimeUnit.SECONDS.sleep(pauseTime);
}
}
}
答案 2 :(得分:2)
滚动窗格将显示您“聚焦”它的组件,它将使用JViewPort作为背景。
无论如何,短篇小说是你有两个选择:
getContentPane().setBackground(new Color(0,0,0));
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.getViewport().setBackground(new Color(0,0,0));
即使它更复杂,我更喜欢第一个,因为它在概念上更正确,因为帧的背景实际上是黑色的。 这是我以前尝试的示例框架:
//imports...
public class ColoredFrame extends JFrame {
public ColoredFrame() {
initComponents();
}
private void initComponents() {
getContentPane().setBackground(new Color(0,0,0));
JLabel area = new JLabel("", JLabel.CENTER);
JScrollPane scrlPane = new JScrollPane(area, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrlPane.setOpaque(false);
scrlPane.getViewport().setOpaque(false);
add(scrlPane);
}
/**
* @param args
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frm = new ColoredFrame();
frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frm.setSize(500,500);
frm.setVisible(true);
}
});
}
}