Java基础知识:Swing用户界面组件(上)

本文深入探讨Swing用户界面设计,介绍其基本体系结构、常用组件及布局管理器,包括模型-视图-控制器模式的应用,以及文本输入、选择组件、滑动条等的详细讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 大纲:
    • Swing的基本体系结构
    • Swing中各种常用的用户组件
    • Java的布局管理器
  • 模型-视图-控制器模式
    • 每个组件都有个要素:
      • 内容(状态、文本)
      • 外观(大小、颜色)
      • 行为(对事件的反应)
    • 有名的设计模式:模型-视图-控制器模式。遵循面向对象设计中的一个基本原则限制一个对象拥有的功能数量。
      • 模型:存储内容。记住:模型是完全不可见的。
      • 视图:显示内容。不一定能够完整显示(如文本框大小限制),而且以何种方式显示取决于自身的构思。
      • 控制器:处理用户输入。如:键盘敲击或鼠标点击,然后决定是否把这些事件转化为对 模型 或 视图 的改变。
    • 模型-视图-控制器模式的一个优点:一个模型可以有多个视图
    • 这种模式吸引Swing设计者的主要原因是:这种模式允许实现可插观感。每个按钮或者文本域的模型都是独立于观感的。
    •  程序员使用Swing组件时,通常不需要考虑 模型-视图-控制器体系结构。每个用户界面元素都有一个 包装器类 来保存模型视图。(JButton JTextField)。这些类的使用者无需为模型操心,仅使用组件包装器即可。
    • 模式只能作为一种指导性的建议而并没有严格的戒律。
    • Swing按钮的模型-视图-控制器分析
      • 对于大多数组件来说,模型类将实现一个名字以 Model结尾接口。如:按钮就实现了 ButtonModel接口。
      • 每个JButton对象都存储了一个按钮模型对象。ButtonModel model = button.getModel()。
      • ButtonModel接口中不包含的信息:模型不存储 按钮标签 或者 图标
      • 通常,每个Swing组件都有一个相关的 后缀为UI的视图对象,但并不是所有的Swing组件都有专门的控制器对象。
      • JButton 仅仅是一个继承了 JComponent 的包装器类。JComponent包含了一个 DefaultButtonModel对象,一些视图数据 和 一个负责按钮视图的 BasicButtonUI对象。
  • 布局管理概述:
    •  面板的默认布局管理器: 流布局管理器(flow layout manager)
      • 一行空间不够,显示在的一行
      • 总是位于面板中央
    • 通常,组件放置于容器中,布局管理器决定容器中的组件具体放置的位置和大小。由于容器继承于组件,所以容器中也可以放置另一个容器。(有例外:JFrame不能放置于容器中,JButton中可以放置其他组件但是无论如何都不会显示出来)
    • 每个容器有一个默认的布局管理器,但可以重新设置。setLayout方法
    • java.awt.Container
      • void setLayout( LayoutManager m )
      • Component add( Component c )
      • Component add( Component c, Object constraints ) //constraints布局管理器理解标识符
    • java.awt.FlowLayout
      • FlowLayout()
      • FlowLayout( int align )
      • FlowLayout( int align, int hgap, int vgap )
        • align    LEFT CENTER或者 RIGHT
        • hgap   以像素为单位的水平间距(若为负值,强行重叠)
        • vgap   以像素为单位的垂直间距
    • 边框布局:
      • 边框布局管理器(border layout manager)是每个 JFrame内容窗格的默认布局管理器。它允许为每个组件选择一个放置位置,东南西北中放置边缘组件,剩余的可用空间由中间组件占据。
      • java.awt.BorderLayout
        • BorderLayout()
        • BorderLayout( int hgap, int vgap )
    • 网格布局
      • java.awt.GridLayout
        • GridLayout( int rows, int columns )
        • GridLayout(int rows, int columns, int hgap, int vgap )
      • 示例程序:(计算器)
        • 布局思路:面板的整体布局为 边框布局。面板又包含一个 按钮(边框布局为“北”) 以及一个 按钮面板(边框布局为“中”)。按钮面板自身的布局为4*4的网格布局。
        • 计算思路:
          • 数字以及“.”按钮触发“插入监听器”,其他符号按钮触发“命令监听器”。
          • 设置一个double类型的变量result记录之前计算出的答案
          • 设置一个boolean类型的变量 start ,标志当先显示的内容是否为“最原始状态”。如果是最原始状态,输入直接覆盖(而不是插入),而且可以区别处理“负号”和“减号”的情况。“负号”视为插入指令,“减号”视为计算指令。
          • 设置一个String 变量 lastCommand 记录上次的command命令。
package calculator;

import java.awt.*;
import javax.swing.*;
public class CalculatorTest {
	public static void main( String[] args ) {
		EventQueue.invokeLater(()->{
			JFrame frame = new JFrame();
			frame.add(new CalculatorPanel());
			frame.setTitle("Calculator");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
			frame.pack();
		});
	}
}
package calculator;

import javax.swing.JPanel;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class CalculatorPanel extends JPanel {
	private JButton display;
	private JPanel buttonPanel;
	private double result;
	private String lastCommand;
	private boolean start;
	
	public CalculatorPanel() {
		setLayout(new BorderLayout());
		
		result = 0;
		lastCommand = "=";
		start = true;
		
		display = new JButton("0");
		display.setEnabled(false);
		add(display, BorderLayout.NORTH );
		
		buttonPanel = new JPanel();
		buttonPanel.setLayout( new GridLayout(4,4) );
		
		InsertAction insert = new InsertAction();
		CommandAction command = new CommandAction();
		
		makeButton("7", insert );
		makeButton("8", insert );
		makeButton("9", insert );
		makeButton("/", command );
		
		makeButton("4", insert );
		makeButton("5", insert );
		makeButton("6", insert );
		makeButton("*", command );
		
		makeButton("1", insert );
		makeButton("2", insert );
		makeButton("3", insert );
		makeButton("-", command );
		
		makeButton("0", insert );
		makeButton(".", insert );
		makeButton("=", command );
		makeButton("+", command );
		
		add(buttonPanel, BorderLayout.CENTER);
		
	}
	
	public void makeButton( String name, ActionListener listener ) {
		JButton button = new JButton(name);
		button.addActionListener(listener);
		buttonPanel.add(button);
	}
	
	public void calculate( double x ) {
		if( lastCommand.equals("+")) result += x;
		else if( lastCommand.equals("-") ) result -= x;
		else if( lastCommand.equals("*") ) result *= x;
		else if( lastCommand.equals("/") ) result /= x;
		else if( lastCommand.equals("=") ) result = x;
		display.setText(""+ result);
	}
	
	private class InsertAction implements ActionListener{
		public void actionPerformed( ActionEvent event ) {
			String input = event.getActionCommand();
			if( start ) {
				display.setText("");
				start = false;
			}
			display.setText(display.getText() + input );
		}
	}
	
	private class CommandAction implements ActionListener{
		public void actionPerformed( ActionEvent event ) {
			String command = event.getActionCommand();
			if(start) {
				if( command.equals("-")) {
					display.setText(command);
					start = false;
				}else lastCommand = command;
			}else {
				calculate(Double.parseDouble(display.getText()));
				lastCommand = command;
				start = true;
			}
		}
	}
}

 

  • 文本输入:
    • JTextField文本域 和 JTextArea文本区 组件,用于获取文本输入。
      • JTextField只能接收 单行文本的输入
      • JTextArea能够接收 多行文本的输入
      • JPassword也只能接收单行文本的输入,但不会将输入的内容显示出来
      • 以上三个类都继承于 JTextComponent 类(抽象类)
    • javax.swing.JTextComponent
      • String getText()
      • void setText(String text)
      • boolean isEditable()
      • void setEditable(boolean b)
    • 文本域
      • javax.swing.JTextField
        • JTextField(int cols) //cols,如果希望文本域最多能输入n个字符,就应该把cols设为n(实际上应多设1、2个字符)。
        • JTextField(String text, int cols) //text初始文本
        • int getColumns()
        • void setColunms(int cols)  //调用了此方法后,需要调用包含这个文本框的 容器的 revalidate方法
      • 如果需要重新计算一个 JFrame 中的所有组件,就必须调用 validate方法
    • 标签和标签组件:
      • 标签是容纳文本的组件,没有修饰,不能响应输入。
      • 文本域没有标识它们的标签。若想用标签标识:
        • 构造一个标签组件(JLabel)
        • 将标签组件放在需要标识的组件位置足够近的地方
      • javax.swing.JLabel
        • JLabel(String text)
        • JLabel(Icon icon)
        • JLabel(String text, int align)
        • JLabel(String text, Icon icon, int align)
        • String getText()
        • void setText(String text)
        • Icon getIcon()
        • void setIcon(Icon icon)
    • 密码域
      • javax.swing.JPasswordField
        • JPasswordField(String text, int columns)
        • void setEchoChar(char echo)
        • char[] getPassword()  //安全起见,使用之后应该覆写
    • 文本区
      • JTextArea()
      • JTextArea(int rows,int cols) //用户并不受限,输入过长,文本会滚动
      • void setColumns(int cols)
      • void setRows(int rows)
      • void append(String newText)
      • void setLineWrap(boolean wrap) //超长是否换行显示
      • void setWordStyleWord(boolean word) //超长时是否 整个长单词 换行 
      • void setTabSize(int c)
      • JTextArea只显示无格式的文本,如果想要显示格式化的文本,就需要使用 JEditorPane类
    • 滚动窗格
      • 在Swing中,文本区没有滚动条。若需要,可以将文本区插入到 滚动窗格(scroll pane) 中。
      • 滚动条会根据实际情况自动出现,自动消失。
      • 这是一种为任意组件添加滚动功能的通用机制,而不是文本区特有
    • 示例程序:(显示一个文本域,一个密码域,和一个带滚动条的文本区)
package text;

import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
public class TextComponentFrame extends JFrame {
	public static void main(String[] args) {
		EventQueue.invokeLater(()->{
			TextComponentFrame frame = new TextComponentFrame();
			frame.setTitle("TextComponentFrame");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
		});
	}
	 
	
	private static final int TEXTAREA_ROWS = 8;
	private static final int TEXTAREA_COLUMNS = 40;
	
	
	
	public TextComponentFrame() {
		setLayout(new BorderLayout());
		JTextField user = new JTextField();
		JPasswordField psw = new JPasswordField();
		
		JPanel northPanel = new JPanel(new GridLayout(2,2));
		JPanel southPanel = new JPanel(); 
		
		//框架北部 布局用户文本域和密码域,并附带相应的标签组件
		northPanel.add(new JLabel("user name: ", SwingConstants.RIGHT) );
		northPanel.add(user);
		northPanel.add(new JLabel("password:", SwingConstants.RIGHT ) );
		northPanel.add(psw);
		add(northPanel, BorderLayout.NORTH);
		
		//中间的可滚动文本区
		JTextArea textArea = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLUMNS);
		JScrollPane scrollPane = new JScrollPane(textArea);
		
		add(scrollPane, BorderLayout.CENTER);
		
		//框架的南部 布局一个居中按钮。点击按键将用户文本以及密码添加到文本区。
		JButton button = new JButton("Insert");
		button.addActionListener(event->{
			textArea.append("User name: " + user.getText() + ", password: " + 
					new String(psw.getPassword()) + "\n");
		});
		
		southPanel.add(button);
		add(southPanel, BorderLayout.SOUTH);
		
		pack();
	}
}

 

  • 选择组件
    • 复选
      • 接收的输入只是 “是” 或 “非”。
      • 对于多个复选框,可同时选0个,一个,多个。
      • javax.swing.JCheckBox
        • JCheckBox(String label)
        • JCheckBox(String label, Icon icon)
        • JCheckBox(String label, boolean state)
        • boolean isSelected()
        • void setSelected(boolean state)
    • 单选钮
      • 只选择几个选项当中的一个
      • 实现:为单选钮组构造一个ButtonGroup对象,然后再将JRadioButton类型的对象添加到按钮组中。
      • javax.swing.JRadioButton
        • JRadioButton(String label, Icon icon)
        • JRadioButton(String label, int state)
      • javax.swing.ButtonGroup
        • void add(AbstractButton b)
        • ButtonModel getSelection()
      • javax.swing.ButtonModel
        • String getActionCommand()
      • javax.swing.AbstractButton
        • void setActionCommand(String s)
    • 示例程序两个:(测试复选框 和 单选钮)
package checkBox;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CheckBoxFrame extends JFrame{
	public static void main(String[] args) {
		EventQueue.invokeLater(()->{
			CheckBoxFrame frame = new CheckBoxFrame();
			frame.setTitle("CheckBoxFrame");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
		});
	}
	
	private JLabel context;
	private JCheckBox bold;
	private JCheckBox italic;
	private static final int FONT_SIZE = 24;
	
	public CheckBoxFrame() {
		JPanel contextPanel = new JPanel();
		context = new JLabel("The ends justify the means.");
		context.setFont( new Font(Font.SERIF, Font.PLAIN, FONT_SIZE) );
		contextPanel.add(context);
		add(contextPanel, BorderLayout.CENTER);
		
		bold = new JCheckBox("Bold", false);
		italic = new JCheckBox("Italic", false);
		JPanel checkBoxPanel = new JPanel();
		
		CheckBoxListener listener = new CheckBoxListener();
		bold.addActionListener(listener);
		italic.addActionListener(listener);
		checkBoxPanel.add(bold);
		checkBoxPanel.add(italic);
		add(checkBoxPanel, BorderLayout.SOUTH);
		pack();
		
	}
		
	private class CheckBoxListener implements ActionListener{
		public void actionPerformed( ActionEvent event ) {
			int mode = 0;
			if( bold.isSelected() ) mode += Font.BOLD;
			if( italic.isSelected() ) mode += Font.ITALIC;
			context.setFont(new Font(Font.SERIF, mode, FONT_SIZE));
		}
	}

	
}
package radioButton;

import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
public class RadioButtonFrame extends JFrame {
	public static void main(String[] args) {
		EventQueue.invokeLater(()->{
			RadioButtonFrame frame = new RadioButtonFrame();
			frame.setTitle("RadioButtonFrame");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
		});
	}
	
	private JLabel context;
	private ButtonGroup buttonGroup;
	private JPanel buttonPanel;
	private static final int DEFAULT_SIZE = 36;
	
	public RadioButtonFrame() {
		JPanel contextPanel = new JPanel();
		context = new JLabel("Young forever.");
		context.setFont(new Font(Font.SERIF, Font.PLAIN, DEFAULT_SIZE));
		
		contextPanel.add(context);
		add(contextPanel, BorderLayout.CENTER);
		
		buttonPanel = new JPanel();
		buttonGroup = new ButtonGroup();
		addRadioButton("Small", 8);
		addRadioButton("Medium",12);
		addRadioButton("Large", 18);
		addRadioButton("Extra Large", 36);
		
		add(buttonPanel, BorderLayout.SOUTH);
		
		pack();
	}
	
	public void addRadioButton( String name, int size ) {
		boolean isSelected = (size == DEFAULT_SIZE);
		JRadioButton button = new JRadioButton(name, isSelected);
		buttonGroup.add(button);
		buttonPanel.add(button);
		button.addActionListener(event->context.setFont( new Font(Font.SERIF, Font.PLAIN, size) ) );
	}
}

 

 

  • 边框:
    • Swing提供了一组很有用的 边框(borders)
    • 可以在 任何 继承了 JComponent 的组件上应用边框。最常用的用途是在一个平板周围放置一个边框,然后用其他用户界面元素填充面板。
    • 调用 BorderFactory的静态方法 创建边框,可以创建不同的可选风格
      • LoweredBevel
      • RaisedBevel
      • Etched
      • Line
      • Matte
      • Empty
    • 可以为边框添加标题,具体的是实现方法是:将边框传递给 BorderFactory.createTitleBorder。
    • 可以将几种边框组合起来使用: BorderFactory.createCompoundBorder 。
    • 调用 JComponent类中的 setBorder方法 将结果边框添加到组件中。
    • API:P495 10th。
    • 示例程序:(通过单选钮选择,为面板设置不同的边框)
package border;

import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;

public class BorderFrame extends JFrame {
	public static void main(String[] args) {
		BorderFrame frame = new BorderFrame();
		frame.setTitle("BorderFrame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	private ButtonGroup group;
	private JPanel buttonPanel;
	private JPanel demoPanel;
	
	
	public BorderFrame() {
		buttonPanel = new JPanel();
		demoPanel = new JPanel();
		group = new ButtonGroup();
		
		addRadioButton("Line", BorderFactory.createLineBorder(Color.CYAN));
		addRadioButton("Matte", BorderFactory.createMatteBorder(10, 10, 10, 10, Color.CYAN));
		addRadioButton("Empty", BorderFactory.createEmptyBorder());
		addRadioButton("Etched", BorderFactory.createEtchedBorder());
		addRadioButton("Lowered Bevel", BorderFactory.createLoweredBevelBorder());
		addRadioButton("Raised Bevel", BorderFactory.createRaisedBevelBorder());

		Border titled = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Border Styles");
		buttonPanel.setBorder(titled);
		setLayout(new GridLayout(2,1) );
		add(buttonPanel);
		add(demoPanel);
		pack();

	}
	
	public void addRadioButton( String name, Border border ) {
		JRadioButton button = new JRadioButton(name);
		button.addActionListener(event->demoPanel.setBorder(border));
		group.add(button);
		buttonPanel.add(button);
	}
}
  • 组合框
    • 单选钮的选项太多--->占据太多空间--->可以选用 组合框(下拉可选列表)
    • JComboBox类提供了组合框的组件
    • JComboBox是一个泛型类。组合框可以调用每个选项的toString方法显示内容。
    • 如果下拉列表框被设为 可编辑的, 就可以向编辑文本一样编辑当前的选项内容
    • getSelectedItem方法获得当前的选项,若组合框可编辑,则当前选项可编辑
    • 如果组合框不可编辑,最好调用 combo.getItemAt(combo.getSelectedIndex()) //能够提供正确的类型
    • addItem 增加选项(添加到列表尾部) /  insertItemAt任何位置插入选项
    • removeItem / removeItemAt
    • 若需要添加大量的选项,效率高的方法: 构造一个 DefaultComboBoxModel ,并调用addElement方法进行加载,然后再调用 JComboBox中的setModel方法。
    • 示例程序(组合框选择文字的风格)
package comboBox;

import javax.swing.JFrame;
import java.awt.*;
import javax.swing.*;
public class ComboBoxFrame extends JFrame {
	public static void main(String[] args) {
		ComboBoxFrame frame = new ComboBoxFrame();
		frame.setTitle("ComboBoxFrame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	private JLabel text;
	private JComboBox<String> items;
	private static final int DEFAULT_SIZE = 24;
	public ComboBoxFrame() {
		text = new JLabel("Ready to soar!Master!!!");
		text.setFont(new Font(Font.SERIF, Font.PLAIN, DEFAULT_SIZE));
		add(text, BorderLayout.CENTER);
		
		items = new JComboBox<>();
		items.addItem(Font.SERIF);
		items.addItem(Font.SANS_SERIF);
		items.addItem(Font.DIALOG);
		items.addItem(Font.DIALOG_INPUT);
		items.addItem(Font.MONOSPACED);
		
		items.addActionListener(event->{
			Font font = new Font(items.getItemAt(items.getSelectedIndex()), Font.PLAIN, DEFAULT_SIZE);
			text.setFont(font);
		});
		
		JPanel comboPanel = new JPanel();
		comboPanel.add(items);
		add(comboPanel, BorderLayout.SOUTH);
		
		pack();
	}
}
  • 滑动条
    • javax.swing.JSlider
      • JSlider()
      • JSlider( int direction )
      • JSlider( int min, int max )
      • JSlider( int min, int max, int initialValue )
      • JSlider( int direction, int min, int max, int initialValue )
      • void setPaintTicks( boolean b ) // 显示标尺
      • void setMajorTickSpacing( int units )  //大标尺标记
      • void setMinorTickSpacing( int units ) //小标尺标记
      • void setPaintLabels(boolean b) //显示标尺标签
      • void setLabelTable(Dictionary table) //设置用于标尺标签的组件。键/值对 ---> new Integer(value)/component
      • void setSnapToTicks(boolean b) //自动对齐最近标尺
      • void setPaintTrack(boolean b) //显示滑动条滑动轨迹
    • 当值发生变化时,ChangeEvent就会发送给所有变化的监听器。需要调用 addChangeListener方法并安装一个实现了ChangeListener接口的对象。
    • 示例程序:
package slider;

import javax.swing.JFrame;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class SliderFrame extends JFrame {
	public static void main(String[] args) {
		SliderFrame frame = new SliderFrame();
		frame.setTitle("SliderFrame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	private JPanel sliderPanel;
	private JTextField text;
	private ChangeListener listener;
	private static final int ICON_WIDTH = 25;
	private static final int ICON_HEIGHT = 35;
	public SliderFrame() {
		sliderPanel = new JPanel();
		sliderPanel.setLayout(new GridBagLayout());
		text = new JTextField("");
		text.setEditable(false);
		
		listener = event->{
			JSlider slider = (JSlider) event.getSource();
			int value = slider.getValue();
			text.setText(""+value);
		};
		//普通滑动条
		JSlider plain = new JSlider();
		addSlider(plain, "Plain");
		
		//带刻度的滑动条
		JSlider ticks = new JSlider();
		ticks.setMajorTickSpacing(20);
		ticks.setMinorTickSpacing(5);
		ticks.setPaintTicks(true);
		addSlider(ticks, "Ticks");
		
		//自动对齐标尺的滑动条
		JSlider snap = new JSlider();
		snap.setMajorTickSpacing(20);
		snap.setMinorTickSpacing(5);
		snap.setPaintTicks(true);
		snap.setSnapToTicks(true);
		addSlider(snap, "Snap to ticks");
		
		//无轨迹滑动条
		JSlider noTrack = new JSlider();
		noTrack.setMajorTickSpacing(20);
		noTrack.setMinorTickSpacing(5);
		noTrack.setPaintTicks(true);
		noTrack.setPaintTrack(false);
		addSlider(noTrack, "No track");
		
		//反向滑动条
		JSlider inverted = new JSlider();
		inverted.setMajorTickSpacing(20);
		inverted.setMinorTickSpacing(5);
		inverted.setPaintTicks(true);
		inverted.setInverted(true);
		addSlider(inverted, "Inverted");
		
		//带数字标尺标签的滑动条
		JSlider labels = new JSlider();
		labels.setMajorTickSpacing(20);
		labels.setMinorTickSpacing(5);
		labels.setPaintTicks(true);
		labels.setPaintLabels(true);
		addSlider(labels, "Labels");
		
		//带字母标尺标签的滑动条
		JSlider alphaLabels = new JSlider();
		alphaLabels.setMajorTickSpacing(20);
		alphaLabels.setMinorTickSpacing(5);
		alphaLabels.setPaintTicks(true);
		Hashtable<Integer, Component> table = new Hashtable<>();
		table.put(0, new JLabel("A"));
		table.put(20, new JLabel("B"));
		table.put(40, new JLabel("C"));
		table.put(60, new JLabel("D"));
		table.put(80, new JLabel("E"));
		table.put(100, new JLabel("F"));
		alphaLabels.setLabelTable(table);
		alphaLabels.setPaintLabels(true);
		addSlider(alphaLabels, "Custom labels");
		
		//带图标标尺标签的滑动条
		JSlider icons = new JSlider();
		icons.setMajorTickSpacing(20);
		icons.setMinorTickSpacing(5);
		icons.setPaintTicks(true);
		Hashtable<Integer, Component> table2 = new Hashtable<>();
		table2.put(0, new JLabel(new ImageIcon(getImage("nine.png"))));
		table2.put(20, new JLabel(new ImageIcon(getImage("ten.png"))));
		table2.put(40, new JLabel(new ImageIcon(getImage("jack.png"))));
		table2.put(60, new JLabel(new ImageIcon(getImage("queen.png"))));
		table2.put(80, new JLabel(new ImageIcon(getImage("king.png"))));
		table2.put(100, new JLabel(new ImageIcon(getImage("ace.png"))));
		icons.setLabelTable(table2);
		icons.setPaintLabels(true);
		addSlider(icons, "Icon labels");
		
		
		add(sliderPanel, BorderLayout.CENTER);
		add(text, BorderLayout.SOUTH);
		pack();
	}
	
	public void addSlider(JSlider s, String description ) {
		s.addChangeListener(listener);
		JPanel panel = new JPanel();
		panel.add(s);
		panel.add(new JLabel(description));
		panel.setAlignmentX(Component.LEFT_ALIGNMENT);
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridy = sliderPanel.getComponentCount();
		gbc.anchor = GridBagConstraints.WEST;
		sliderPanel.add( panel, gbc );
	}
	
	private Image getImage(String file) {
		return new ImageIcon(file).getImage().getScaledInstance(ICON_WIDTH, ICON_HEIGHT, Image.SCALE_DEFAULT);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值