Unlike multithreading and generics, Swing is mainly used.
Below are the main codes and comments, less talk.
(1) Shared code
All classes that inherit the JFrame need to have a starting framework to include them. The framework is given directly here. The following points will not be repeated.
package Event;
import java.awt.*;
import javax.swing.*;
/**
*
* @author QuinnNorris
* Shared code
*/
public class BaseFrame {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Open a thread, all Swing components must be configured by event dispatch threads, which transfer mouse click and key control to user interface components.
EventQueue.invokeLater(new Runnable() {
// Anonymous inner class, an example of Runnable interface, implements the run method
public void run() {
JFrame frame = new *********();
// Replace the * sign with a subclass of the JFrame you implemented to implement your code
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
// Maximizing windows
frame.setTitle("Christmas");
// Setting the title of the window
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Choose the action that happens when the user closes the framework. Sometimes the window needs to be hidden, and this method can't be used to exit directly.
frame.setVisible(true);
// Visualize windows so that users can add content to them before they first see them
}
});
}
}
Output: A basic common framework is obtained, and later content can be written in other classes and put into this framework.
(2) Button events
package Event;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
*
* @author QuinnNorris Button event
*/
public class ButtonFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ButtonFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// Set default width and height
buttonPanel = new JPanel();
// Instantiate JPanel panel objects in the instance domain of a class
makeButton("yellow",Color.YELLOW);
makeButton("blue",Color.BLUE);
makeButton("red",Color.RED);
//Call the makeButton method to create and add buttons
add(buttonPanel);
// We added the panel with the buttons to the original frame.
}
/**
* Create buttons by means of methods, and complete the operation of associating monitor and adding panel
* @param name Create the button's logo
* @param backgroundColor Click the button to change the color. Anonymous inner classes can only access final-modified variables, so use final.
*/
public void makeButton(String name,final Color backgroundColor){
JButton colorButton = new JButton(name);
//With different identification names, we create buttons
buttonPanel.add(colorButton);
//We will add the button we created to the panel
//Anonymous inner class, create an instance of ActionListener
colorButton.addActionListener(new ActionListener(){
/**
* When the button is clicked, the actionPerformed method is automatically invoked
*/
public void actionPerformed(ActionEvent event) {
buttonPanel.setBackground(backgroundColor);
// Call the setBackground method to set the background color
}
});
}
}
Output: In a full-screen window, there are three buttons with different colors above. When pressed, the background color will change accordingly.
(3) Subject change
package Event;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
/**
*
* @author QuinnNorris Change theme
*/
public class MetalFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public MetalFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// Set default width and height
buttonPanel = new JPanel();
// Instantiate JPanel panel objects in the instance domain of a class
UIManager.LookAndFeelInfo[] infos = UIManager
.getInstalledLookAndFeels();
// Calling this static method, we get all the topics
makeButton(infos);
// Call the makeButton method to implement the theme
add(buttonPanel);
// We added the panel with the buttons to the original frame.
}
/**
* Create all theme buttons and associate them with the monitor
*
* @param infos
* An array containing all types of topics
*/
private void makeButton(final UIManager.LookAndFeelInfo[] infos) {
for (UIManager.LookAndFeelInfo info : infos) {
JButton button = new JButton(info.getName());
// Traveling through all topics with a for-each loop
final UIManager.LookAndFeelInfo innerInfo = info;
// Copy info and define bit final type to facilitate the use of internal classes
buttonPanel.add(button);
// We will add the button we created to the panel
// Anonymous inner class, create an instance of ActionListener
button.addActionListener(new ActionListener() {
/**
* When the button is clicked, the actionPerformed method is automatically invoked
*/
public void actionPerformed(ActionEvent ae) {
try {
UIManager.setLookAndFeel(innerInfo.getClassName());
// Call the setLookAndFeel method to change the theme
SwingUtilities.updateComponentTreeUI(buttonPanel);
// With this static approach, the changed theme is applied immediately
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
}
Output results: There are five themes buttons above the window, each with their respective themes'names, which will be changed immediately after clicking.
(4) Button and keystroke
package Event;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* @author QuinnNorris Button and keystroke action
*/
public class ActionFrame extends JFrame {
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ActionFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// Set default width and height
buttonPanel = new JPanel();
// Instantiate JPanel panel objects in the instance domain of a class
Action yellowAction = new ColorAction("Yellow", Color.YELLOW);
// Create a ColorAction object of your own definition, yellowAction
buttonPanel.add(new JButton(yellowAction));
// Create a button whose properties are retrieved from the Action provided
add(buttonPanel);
// We added the panel with the buttons to the original frame.
InputMap imap = buttonPanel
.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// We set the InputMap of the JPanel object as the second input map and create the object.
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
// Setting the combination of keystroke input ctrl+Y in imap by calling the static method of keystroke class KeyStroke
// The second parameter is a flag parameter, which is stored in imap in the form of key-value pairs.
ActionMap amap = buttonPanel.getActionMap();
// We can't map InputMap directly to Action. We need to transition with Action Map.
// Getting amap objects by getACtionMap method in JPanel
amap.put("panel.yellow", yellowAction);
// Combine keystroke combinations corresponding to markup parameters and corresponding actions in imap
}
public class ColorAction extends AbstractAction {
/**
* ColorAction Constructor that stores key-value pairs
* @param name The name of the button
* @param c The button corresponds to the color displayed after clicking
*/
public ColorAction(String name, Color c) {
putValue(Action.NAME, name);
putValue(Action.SHORT_DESCRIPTION,
"Set panel color to " + name.toLowerCase());
putValue("color", c);
//Set some key-value pair mappings in the constructor, and the properties of these settings will be read by JPanel
}
/**
* When a button clicks or keystrokes, the actionPerformed method is automatically invoked.
*/
public void actionPerformed(ActionEvent event) {
Color c = (Color) getValue("color");
buttonPanel.setBackground(c);
// Call the setBackground method to set the background color
}
}
}
Output results: There is a yellow button above the window. The background can be yellowed by clicking or ctrl+Y. The mouse hovers over the window for a period of time to display the explanatory text.
(5) Mouse operation
package Event;
import javax.swing.*;
/**
*
* @author QuinnNorris
* Inheriting subclasses of JFrame to package Component object content
*/
public class MouseFrame extends JFrame{
public MouseFrame(){
add(new MouseComponent());
//Add an instance of JComponent to the framework
pack();
}
}
package Event;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
/**
*
* @author QuinnNorris Mouse click
*/
public class MouseComponent extends JComponent {
private static final int SIDELENGTH = 100;
// Define the edge length of the created square
private ArrayList<Rectangle2D> squares;
// Declare a collection of squares
private Rectangle2D current;
// The class used to describe a rectangle in the java class library, whose object can be regarded as a rectangle
/**
* Constructor method for initialization
*/
public MouseComponent() {
squares = new ArrayList<>();
current = null;
addMouseListener(new MouseHandler());
// Add a class we implemented that inherits MouseListener for monitoring mouse clicks
addMouseMotionListener(new MouseMotionHandler());
// Add another implementation class that inherits MouseMotionListener for monitoring mouse movement
}
/**
* We override this to print graphics, which will be called automatically.
*
* @param g
* Graphics A parent class of 2D we're going to use
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Convert to the type we need to use
for (Rectangle2D r : squares)
g2.draw(r);
// Draw each square in the array
}
/**
* Determine whether there is a graph in this coordinate
*
* @param p
* A pair of current coordinate values of x and y
* @return Returns the existing graph or null
*/
public Rectangle2D find(Point2D p) {
for (Rectangle2D r : squares) {
if (r.contains(p))
//contains method to determine whether coordinates are within the boundaries of a graph
return r;
}
// If there is a coordinate of this position in the square array, it indicates that the position is not empty.
// Returns the object at this location
return null;
// Otherwise, if nothing happens, return null
}
/**
* Add a graph at this coordinate position
* @param p Coordinate position
*/
public void add(Point2D p) {
double x = p.getX();
double y = p.getY();
//Get the coordinates of x and y
current = new Rectangle2D.Double(x - SIDELENGTH / 2,
y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
//Construct a new square with the obtained coordinates and given side lengths and assign it to current.
squares.add(current);
//Add current to square queue
repaint();
//Redraw images
}
/**
* Remove the graphics for this location
* @param s Represents the rectangular object to be removed
*/
public void remove(Rectangle2D s) {
if (s == null)
return;
//If the content to be removed is empty, return it directly
if (s == current)
current = null;
//If the content to be removed is the same as what current is pointing to, empty the current
//Avoid unnecessary mistakes
squares.remove(s);
//Delete s directly from the square list
repaint();
//Redraw images
}
/**
*
* @author QuinnNorris Mouse Click Control Class Inherited from MouseAdapter Class
*/
private class MouseHandler extends MouseAdapter {
/**
* Click Mouse Operation
*/
public void mousePressed(MouseEvent event) {
current = find(event.getPoint());
// Assign the object of the coordinate of the point clicked by the mouse to current
if (current == null)
//If there is no object at this point, the current empty position
add(event.getPoint());
//Draw a square at this point
}
/**
* Mouse double-click operation
*/
public void mouseClicked(MouseEvent event) {
current = find(event.getPoint());
// Assign the object of the coordinate of the point clicked by the mouse to current
if (current != null && event.getClickCount() >= 2)
//If this point has an object, and the number of clicks on the mouse is greater than 2
remove(current);
//Remove current
}
}
/**
*
* @author QuinnNorris
* Mouse Move Drag Class
*/
private class MouseMotionHandler implements MouseMotionListener {
/**
* Mouse cursor moved to component, but called when not pressed
*/
public void mouseMoved(MouseEvent event) {
if (find(event.getPoint()) == null)
//If the mouse is not empty
setCursor(Cursor.getDefaultCursor());
//Set the image of the cursor to the default image
else
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
//If there is an image in the current position, set the cursor style to hand
}
/**
* The mouse cursor is pressed on the component and called when dragged
*/
public void mouseDragged(MouseEvent event) {
if (current != null) {
//Because before calling this method, the method that clicks the mouse must be called.
//So let's just judge: if the current is not empty now
int x = event.getX();
int y = event.getY();
//Get coordinates
current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2,
SIDELENGTH, SIDELENGTH);
//Finally, draw the graphics when the mouse is down
repaint();
//Redraw images
}
}
}
}
Output: In this form, a single mouse click creates a small square with 100 pixels of edge length. In a square, double-clicking or more clicks delete the square. You can hold the square and drag it, and when you indicate the square area, the mouse pointer becomes a hand pointer.