Skip to content

Instantly share code, notes, and snippets.

@miracleyoo
Last active December 12, 2019 04:50
Show Gist options
  • Save miracleyoo/4bca71d404efd4b85dd473efe9c11d18 to your computer and use it in GitHub Desktop.
Save miracleyoo/4bca71d404efd4b85dd473efe9c11d18 to your computer and use it in GitHub Desktop.
[Swing Background Panel] #Java #GUI #Swing
/**
* Support custom painting on a panel in the form of
*
* a) images - that can be scaled, tiled or painted at original size
* b) non solid painting - that can be done by using a Paint object
*
* Also, any component added directly to this panel will be made
* non-opaque so that the custom painting can show through.
*/
package com.miracleyoo.utils;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class BackgroundPanel extends JPanel {
public static final int SCALED = 0;
public static final int TILED = 1;
public static final int ACTUAL = 2;
private Paint painter;
private Image image;
private int style = SCALED;
private float alignmentX = 0.5f;
private float alignmentY = 0.5f;
private boolean isTransparentAdd = true;
/*
* Set image as the background with the SCALED style
*/
public BackgroundPanel(Image image) {
this(image, SCALED);
}
/*
* Set image as the background with the specified style
*/
public BackgroundPanel(Image image, int style) {
setImage(image);
setStyle(style);
setLayout(new BorderLayout());
}
/*
* Set image as the backround with the specified style and alignment
*/
public BackgroundPanel(Image image, int style, float alignmentX, float alignmentY) {
setImage(image);
setStyle(style);
setImageAlignmentX(alignmentX);
setImageAlignmentY(alignmentY);
setLayout(new BorderLayout());
}
/*
* Use the Paint interface to paint a background
*/
public BackgroundPanel(Paint painter) {
setPaint(painter);
setLayout(new BorderLayout());
}
/*
* Set the image used as the background
*/
public void setImage(Image image) {
this.image = image;
repaint();
}
/*
* Set the style used to paint the background image
*/
public void setStyle(int style) {
this.style = style;
repaint();
}
/*
* Set the Paint object used to paint the background
*/
public void setPaint(Paint painter) {
this.painter = painter;
repaint();
}
/*
* Specify the horizontal alignment of the image when using ACTUAL style
*/
public void setImageAlignmentX(float alignmentX) {
this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
repaint();
}
/*
* Specify the horizontal alignment of the image when using ACTUAL style
*/
public void setImageAlignmentY(float alignmentY) {
this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
repaint();
}
/*
* Override method so we can make the component transparent
*/
public void add(JComponent component) {
add(component, null);
}
/*
* Override to provide a preferred size equal to the image size
*/
@Override
public Dimension getPreferredSize() {
if (image == null)
return super.getPreferredSize();
else
return new Dimension(image.getWidth(null), image.getHeight(null));
}
/*
* Override method so we can make the component transparent
*/
public void add(JComponent component, Object constraints) {
if (isTransparentAdd) {
makeComponentTransparent(component);
}
super.add(component, constraints);
}
/*
* Controls whether components added to this panel should automatically
* be made transparent. That is, setOpaque(false) will be invoked.
* The default is set to true.
*/
public void setTransparentAdd(boolean isTransparentAdd) {
this.isTransparentAdd = isTransparentAdd;
}
/*
* Try to make the component transparent.
* For components that use renderers, like JTable, you will also need to
* change the renderer to be transparent. An easy way to do this it to
* set the background of the table to a Color using an alpha value of 0.
*/
private void makeComponentTransparent(JComponent component) {
component.setOpaque(false);
if (component instanceof JScrollPane) {
JScrollPane scrollPane = (JScrollPane) component;
JViewport viewport = scrollPane.getViewport();
viewport.setOpaque(false);
Component c = viewport.getView();
if (c instanceof JComponent) {
((JComponent) c).setOpaque(false);
}
}
}
/*
* Add custom painting
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Invoke the painter for the background
if (painter != null) {
Dimension d = getSize();
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(painter);
g2.fill(new Rectangle(0, 0, d.width, d.height));
}
// Draw the image
if (image == null) return;
switch (style) {
case SCALED:
drawScaled(g);
break;
case TILED:
drawTiled(g);
break;
case ACTUAL:
drawActual(g);
break;
default:
drawScaled(g);
}
}
/*
* Custom painting code for drawing a SCALED image as the background
*/
private void drawScaled(Graphics g) {
Dimension d = getSize();
g.drawImage(image, 0, 0, d.width, d.height, null);
}
/*
* Custom painting code for drawing TILED images as the background
*/
private void drawTiled(Graphics g) {
Dimension d = getSize();
int width = image.getWidth(null);
int height = image.getHeight(null);
for (int x = 0; x < d.width; x += width) {
for (int y = 0; y < d.height; y += height) {
g.drawImage(image, x, y, null, null);
}
}
}
/*
* Custom painting code for drawing the ACTUAL image as the background.
* The image is positioned in the panel based on the horizontal and
* vertical alignments specified.
*/
private void drawActual(Graphics g) {
Dimension d = getSize();
Insets insets = getInsets();
int width = d.width - insets.left - insets.right;
int height = d.height - insets.top - insets.left;
float x = (width - image.getWidth(null)) * alignmentX;
float y = (height - image.getHeight(null)) * alignmentY;
g.drawImage(image, (int) x + insets.left, (int) y + insets.top, this);
}
}
//////////////////////////////////////////////////////////////////////////////
/////////////////////////// USAGE ////////////////////////////////
/////////////// Attention: Used with NoneFrame Class ///////////////////
//////////////////////////////////////////////////////////////////////////////
/**
* Functionality: A cool welcome interface. It will ask user to select
* a *.s file and parse the file into a list of map. Each line will be
* put into the corresponding array as a item.
* Feature: It initialize a window which is boarder-less and mouse-drag-able.
* Also, a automatically scalable background image is added.
* */
package com.miracleyoo.UIs;
import com.miracleyoo.utils.BackgroundPanel;
import com.miracleyoo.utils.NoneFrame;
import com.miracleyoo.utils.ParseFile;
import com.miracleyoo.utils.UICommonUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
public class CoolMainUI {
private BackgroundPanel MainPanel; // The main panel.
private CoolMainUI() throws IOException {
// Initialize the MainPanel
BufferedImage img = null;
img = ImageIO.read(new File("Assets/image_01.jpg"));
MainPanel = new BackgroundPanel(img, BackgroundPanel.SCALED, 1.0f, 0.5f);
GradientPaint paint = new GradientPaint(0, 0, Color.BLUE, 600, 0, Color.RED);
MainPanel.setPaint(paint);
// Initialize the FileSelectedCap
FileSelectedCap = new JLabel("<html><font color='white'>Welcome! Please select a *.s file to start!</font></html>");
FileSelectedCap.setHorizontalAlignment(SwingConstants.CENTER);
FileSelectedCap.setVerticalAlignment(SwingConstants.CENTER);
FileSelectedCap.setFont(new Font("Dialog", Font.BOLD, 20));
// Initialize the ChooseFileBtn
ChooseFileBtn = new JButton();
ChooseFileBtn.setText("<html><font color='white'>Select a *.s file to start</font></html>");
ChooseFileBtn.setFont(new Font("Dialog", Font.BOLD, 15));
ChooseFileBtn.setOpaque(false);
ChooseFileBtn.setContentAreaFilled(false);
ChooseFileBtn.setBorderPainted(false);
// Initialize the ExitBtn
ExitBtn = new JButton();
ExitBtn.setText("<html><font color='white'>×</font></html>");
ExitBtn.setFont(new Font("Dialog", Font.PLAIN, 12));
ExitBtn.setOpaque(false);
ExitBtn.setContentAreaFilled(false);
ExitBtn.setBorderPainted(false);
// Action on ChooseFileBtn
ChooseFileBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
FileDialog fd = new FileDialog(new JFrame(), "Choose a file", FileDialog.LOAD);
System.out.println(System.getProperty("user.dir"));
// Set the default folder is a subfolder of current package root path.
fd.setDirectory(Paths.get(System.getProperty("user.dir"), "asm_code").toString());
fd.setFilenameFilter((dir, name) -> name.endsWith(".s"));
fd.setVisible(true);
String fileName = fd.getFile();
String filePath = fd.getDirectory();
if (fileName == null)
System.out.println("You cancelled the choice");
else
System.out.println("You chose " + filePath + fileName);
try {
// Load and try to parse the file
selectedFileName = filePath + fileName;
listFlagMap = ParseFile.parseFile(new File(selectedFileName));
Object[][] operandListArray = listFlagMap.get("textList").toArray(new Object[0][0]);
Object[][] dataListArray = listFlagMap.get("dataList").toArray(new Object[0][0]);
DataUIFrame = new DataUI(operandListArray, dataListArray);
MainFrame.dispose();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
// Action on ExitBtn: Exit the program
ExitBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) throws IOException {
// Initialize the MainFrame and set bounds
CoolMainUI coolMainUI = new CoolMainUI();
MainFrame.setSize(frameSize[0], frameSize[1]);
UICommonUtils.makeFrameToCenter(MainFrame);
MainFrame.setContentPane(coolMainUI.MainPanel);
MainFrame.getContentPane().setLayout(null);
// Set bounds of the components
coolMainUI.FileSelectedCap.setBounds(0, 10, MainFrame.getWidth() - 20, 30);
coolMainUI.ExitBtn.setBounds(MainFrame.getWidth() - 30, 0, 30, 22);
coolMainUI.ChooseFileBtn.setBounds(0, MainFrame.getHeight() - 60, MainFrame.getWidth(), 60);
// Add components to the MainFrame
MainFrame.getContentPane().add(coolMainUI.ChooseFileBtn);
MainFrame.getContentPane().add(coolMainUI.ExitBtn);
MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MainFrame.setVisible(true);
MainFrame.setResizable(false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment