13.2 JList类
JList组件是用于由一个选项集合中选择一个或多个项目的基本Swing组件。我们向用户展示选项列表,依据于组件的选择模式,用户可以选择一个或多个。
三个关键元素及其实现定义了JList结构:
用于存储JList数据的数据模型,由ListModel接口定义。
用于绘制JList的单元渲染器,由ListCellRenderer接口描述。
用于选择JList元素的选择模式,由ListSelectionModel接口描述。
13.2.1 创建JList组件
JList组件有四个构造函数,可以允许我们基于我们的初始数据结构创建JList实例:
public JList()
JList jlist = new JList();
public JList(Object listData[])
String labels[] = { "Chardonnay", "Sauvignon", "Riesling", "Cabernet", "Zinfandel",
"Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah", "Gewürztraminer"};
JList jlist = new JList(labels);
public JList(Vector listData)
Vector vector = aBufferedImage.getSources();
JList jlist = new JList(vector);
public JList(ListModel model)
ResultSet results = aJDBCStatement.executeQuery("SELECT colName FROM tableName");
DefaultListModel model = new DefaultListModel();
while (result.next())
model.addElement(result.getString(1));
JList jlist = new JList(model);
如果我们使用无参数的构造函数,我们可以稍后填充数据。然而,如果我们使用数组或是Vector构造函数,如果不修改整个模式,那么我们就不能修改内容。
注意,如果我们希望显示一些内容而不是每一个数组元素的toString()结果,可以查看本章稍后的“渲染JList元素”来了解如何实现。
13.2.2 JList属性
在创建了JList组件之后,我们可以修改其每一个属性。表13-5显示了JList的32个属性。
JList属性中的多个都与选择过程有关。例如,anchorSelectionIndex, leadSelectionIndex, maxSelectionIndex, minSelectionIndex, selectedIndex与selectedIndices处理被选中行的索引,而selectedValue与selectedValues与被选中元素的内容有关。anchorSelectionIndex是ListDataEvent最近的index0,而leadSelectionIndex则是最近的index1。
要控制所显示的可视行的数目,设置JList的visibleRowCount属性。这个属性的默认设置为8。
13.2.3 滚动JList组件
当我们使用JList组件时,如果我们希望允许用户在所有的选项中进行选择,我们必须将组件放置在一个JScrollPane中。如果我们没有将其放置在一个JScrollPane中,而默认显示的行数小于数据模型的尺寸,或者是没有足够的空间来显示行,则其他的选项不会显示。当放置在JScrollPane中时,JList提供了一个垂直滚动条来在所有的选项中移动。
如果我们没有将JList放置在JScrollPane中,并且选项的数目超出了可用空间时,只有上部的选项组可见,如图13-4所示。
提示,当我们看到了一个类实现了Scrollable接口,我们就应该想起在将其添加到程序之前需要将其放在JScrollPane中。
JScrollPane依赖于preferredScrollableViewportSize属性设置所提供的维度来确定面板内容的最优尺寸。当JList的数据模型为空时,则会使用每个可见行16像素高256像素宽的默认尺寸。否则宽度通过遍历所有的行来查找最宽的行来确定,而高度是通过第一行的高度来确定。
为了快速确定JScrollPane视图区域的尺寸,我们可以通过设置prototypeCellValue属性来定义一个原型行。我们必须保证原型toString()的值足够宽与足够高从而适应JList中的所用内容。然后JScrollPane基于原型视图区域的尺寸,从而JList就没有必要来询问每一行的尺寸;相反,只需要询问原型的尺寸即可。
我们也可以通过为fixedCellHeight与fixedCellWidth属性指定尺寸来改善性能。设置这些属性是避免JList询问每一行渲染尺寸的另一种方法。设置两个属性是使得JList确定在视图区域中尺寸的最快的方法。当然,这也是最不灵活的方法,因为他保证当内容发生变化时JList的选项不会变宽(或变短)。然而,如果我们在数据模型中有大量的条目,这些灵活性的缺失对于改善性能是值得的。图13-5帮助我们理解JList的一些尺寸功能。
用来生成图13-5的源码显示在列表13-3中。图中间的列表包含超出1000个固定尺寸的行。顶部的列表显示了我们可以通过setVisibleRowCount()方法设置可视行的数目。然而,因为列表并没有位于JScrollPane中,行数目限制的请求会被忽略。
package swingstudy.ch13;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
public class SizingSamples {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
String labels[] = { "Chardonnay", "Sauvignon", "Riesling", "Cabernet",
"Zinfandel", "Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah", "Gewurztraminer"};
JFrame frame = new JFrame("Sizing Samples");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JList jlist1 = new JList(labels);
jlist1.setVisibleRowCount(4);
DefaultListModel model = new DefaultListModel();
for(int i=0; i<100; i++) {
for(int j=0; j<10; j++) {
model.addElement(labels[j]);
}
}
JScrollPane scrollPane1 = new JScrollPane(jlist1);
frame.add(scrollPane1, BorderLayout.NORTH);
JList jlist2 = new JList(model);
jlist2.setVisibleRowCount(4);
jlist2.setFixedCellHeight(12);
jlist2.setFixedCellWidth(200);
JScrollPane scrollPane2 = new JScrollPane(jlist2);
frame.add(scrollPane2, BorderLayout.CENTER);
JList jlist3 = new JList(labels);
jlist3.setVisibleRowCount(4);
frame.add(jlist3, BorderLayout.SOUTH);
frame.setSize(300, 350);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
除了将JList放在JScrollPane中以外,我们可以确定哪些选项是可见或是请求特定的元素可见。firstVisibleIndex与lastVisibleIndex属性使得我们可以确定在JScrollPane中哪些选项是当前可见的。如果没有选项可见,两个方法都会返回-1;这通常在数据模型为空的情况下发生。要请求一个特定的元素可见,使用public void ensureIndexIsVisible(int index)方法。例如,要编程将列表移动到顶部可以使用下面的代码:
jlist.ensureIndexIsVisible(0);
13.2.4 渲染JList元素
JList中的每一个元素被称之为单元。每一个JList都有一个已安装的单元渲染器,当列表需要绘制时渲染器绘制每一个单元。默认的渲染器,DefaultListCellRenderer是JLable的一个子类,这就意味着我们可以使用文本或是图标作为单元的图形显示。这可以满足大多数用户的需要,但是有时单元的外观需要进行某些定制。耏 一,每一个JList至多只有一个安装的渲染器,自定义需要我们替换已安装的渲染器。
ListCellRender接口与DefaultListCellRenderer类
JList有一个已安装的渲染器。实现了ListCellRender接口的类提供了这个渲染器。
public interface ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus);
}
当需要绘制单元时,接口的核心方法被调用。返回的渲染器为列表中的单元提供特定的渲染。Jlist使用渲染来绘制元素,然后获取下一个渲染器。
一个到JList的引用会被提供给getListCellRendererComponent()方法,从而渲染器可以共享显示特性。选中的value包含列表数据模型在位置index上的对象。索引由数据模型的开始处由0开始。最后两个参数允许我们基于单元的状态自定义单元的外观,也就是他是否被选中或是具有输入焦点。
列表13-4显示了一个演示这种技术的渲染器。这个渲染器的核心不同之处在于具有输入焦点的单元有一个带有标题的边框。在渲染器被创建之后,我们通过设置JList的cellRenderer属性来安装。
提示,由于性能的原因,最好不要在getListCellRendererComponent()方法创建实际的渲染器。可以派生Component并返回this或是创建一个类变量来存储Component的实例,然后进行自定义并返回。
package swingstudy.ch13;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
public class FocusedTitleListCellRenderer implements ListCellRenderer {
protected static Border noFocusBorder = new EmptyBorder(15, 1, 1, 1);
protected static TitledBorder focusBorder = new TitledBorder(LineBorder.createGrayLineBorder(), "Focused");
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
public String getTitle() {
return focusBorder.getTitle();
}
public void setTitle(String newValue) {
focusBorder.setTitle(newValue);
}
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
// TODO Auto-generated method stub
JLabel renderer = (JLabel)defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
renderer.setBorder(cellHasFocus ? focusBorder : noFocusBorder);
return renderer;
}
}
注意,当创建我们自己的渲染器时一个觉错误就是忘记使得渲染器组件非透明。这会使得渲染器的背景颜色被忽略,并且列表容器的背景外漏。使用DefaultListCellRenderer类,渲染器组件已经是不透明的了。
列表13-5显示了一个使用这个新渲染器的示例程序。他并没有做任何特殊的事情,而只是安装了刚才创建的自定义单元渲染器。
package swingstudy.ch13;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
public class CustomBorderSample {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
String labels[] = {"Chardonnay", "Sauvignon", "Riesling", "Cabernet",
"Zinfandel", "Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah",
"Gewurztraminer"
};
JFrame frame = new JFrame("Custom Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JList jlist = new JList(labels);
ListCellRenderer renderer = new FocusedTitleListCellRenderer();
jlist.setCellRenderer(renderer);
JScrollPane sp = new JScrollPane(jlist);
frame.add(sp, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
图13-6显示了示例程序的输出。
创建复杂的ListCellRenderer
有时,当数据模型由每个元素中的多个复杂数据组成,不能由文本字符串表示的内容,自定义的单元渲染器(类似于图13-6所示)是必需的。例如,列表13-6显示了一个示例的源码,其中每一个数据模型的元素由字体,前景色,图标与文本字符串组成。保证渲染器中这些元素的正确使用简单的涉及到在配置渲染器组件方面的更多工作。在这个特定的例子中,数据存储在数据模型中数组的每个元素之中。我们可以简单的定义一个新类或是使用散列表。
package swingstudy.ch13;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
public class ComplexCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
// TODO Auto-generated method stub
Font theFont = null;
Color theForeground = null;
Icon theIcon = null;
String theText = null;
JLabel renderer = (JLabel)defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value instanceof Object[]) {
Object values[] = (Object[])value;
theFont = (Font)values[0];
theForeground = (Color)values[1];
theIcon = (Icon)values[2];
theText = (String)values[3];
}
else {
theFont = list.getFont();
theForeground = list.getForeground();
theText = "";
}
if(!isSelected) {
renderer.setForeground(theForeground);
}
if(theIcon != null) {
renderer.setIcon(theIcon);
}
renderer.setText(theText);
renderer.setFont(theFont);
return renderer;
}
}
渲染器很少自定义DefaultListCellRenderer返回的渲染器组件。自定义基于作为数组传递给getListCellRendererComponent()方法的value参数的数据模型值。列表13-7显示了测试类。这个演示程序重用了第4章所创建的DiamondIcon。大部分代码用于数据模型的初始化。
package swingstudy.ch13;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import swingstudy.ch04.DiamondIcon;
public class ComplexRenderingSample {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
Object elements[][] = {
{new Font("Helvetica", Font.PLAIN, 20), Color.RED, new DiamondIcon(Color.BLUE), "Help"},
{new Font("TimesRoman", Font.BOLD, 14), Color.BLUE, new DiamondIcon(Color.GREEN), "Me"},
{new Font("Courier", Font.ITALIC, 18), Color.GREEN, new DiamondIcon(Color.BLACK), "I'm"},
{new Font("Helvetica", Font.BOLD|Font.ITALIC, 12), Color.GRAY, new DiamondIcon(Color.MAGENTA), "Trapped"},
{new Font("TimesRoman", Font.PLAIN, 32), Color.PINK, new DiamondIcon(Color.YELLOW), "Inside"},
{new Font("Courier", Font.BOLD, 16), Color.YELLOW, new DiamondIcon(Color.RED), "This"},
{new Font("Helvetica", Font.ITALIC, 8), Color.DARK_GRAY, new DiamondIcon(Color.PINK), "Computer"}
};
JFrame frame = new JFrame("Complex Renderer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JList jlist = new JList(elements);
ListCellRenderer renderer = new ComplexCellRenderer();
jlist.setCellRenderer(renderer);
JScrollPane scrollPane = new JScrollPane(jlist);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
程序的输出结果如图13-7所示。
提示,当我们创建自己的渲染组件时,我们将会发现最好由默认的列表单元渲染器开始。这可以使得我们专注于我们感兴趣的特定细节。否则,我们就需要考虑所有事情,例如默认选择的前景与背景颜色,以及我们是否记得使得组件非透明。当然,如果我们希望亲自配置所有事情,自由去做就是了。
13.2.5 选择JList元素
默认情况下,所有的JList组件处于多项选择模式。这意味着我们可以选择组件中的多个元素。我们如何选择多个元素依赖于我们正在使用的用户界面。例如,对于Ocean观感界面,Ctrl-select可以作为选择切换,而Shift-select可以作为一种范围选择的方法。
ListSelectionModel接口与DefaultListSelectionModel类
ListSelectionModel接口的实现控制JList组件的选择机制。在这里显示的接口定义定义了用于不同选择模式的常量并且描述了如何管理ListSelectionListener对象的列表。他同时提供了一种方法来描述多个内部选择。
public interface ListSelectionModel {
// Constants
public final static int MULTIPLE_INTERVAL_SELECTION;
public final static int SINGLE_INTERVAL_SELECTION;
public final static int SINGLE_SELECTION;
// Properties
public int getAnchorSelectionIndex();
public void setAnchorSelectionIndex(int index);
public int getLeadSelectionIndex();
public void setLeadSelectionIndex(int index);
public int getMaxSelectionIndex();
public int getMinSelectionIndex();
public boolean isSelectionEmpty();
public int getSelectionMode();
public void setSelectionMode(int selectionMode);
public boolean getValueIsAdjusting();
public void setValueIsAdjusting(boolean valueIsAdjusting);
// Listeners
public void addListSelectionListener(ListSelectionListener x);
public void removeListSelectionListener(ListSelectionListener x);
// Other methods
public void addSelectionInterval(int index0, int index1);
public void clearSelection();
public void insertIndexInterval(int index, int length, boolean before);
public boolean isSelectedIndex(int index);
public void removeIndexInterval(int index0, int index1);
public void removeSelectionInterval(int index0, int index1);
public void setSelectionInterval(int index0, int index1);
}
其中有三个不同的选择模式。表13-6中包含了每个模式的名字及其描述。
图13-8显示了每个选择模式的结果。
要修改JList的选择模式,将selectionModel属性设置为表13-6中的一个ListSelectionModel常量。例如,下面的代码可以将一个列表的修改为单选模式:
JList list = new JList(...);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
DefaultListSelectionModel类是ListSelectionModel接口的默认实现。我们可以尝试表13-7中所示的九个属性来了解当前的选中范围。
当selectionEmpty属性为false时选择模式可以显示我们当前在多项选择模式中使用的是哪一种。如果是使用public boolean isSelectedIndex(int index)方法选中的,则只需要简单的查询最小与最大选中索引中的每一个索引。因为多项选择模式支持不连续的区域,这是确定哪一个被选中的唯一方法。然而,JList的selectedIndeices属性提供了这种信息,而不需要我们手动检测。
使用ListSelectionListener监听JList事件
如果我们希望了解何时JList的元素被选中,我们需要向JList或是ListSelectionModel关联一个ListSelectionListener。Jlist的addListListSelectionListener()与removeListSelectionListener()方法只会委托给底层的ListSelectionModel。当被选中的元素集合发生变化时,所关联的监听器对象会得到通知。接口定义如下:
public interface ListSelectionListener extends EventListener {
public void valueChanged(ListSelectionEvent e);
}
监听器所接收的ListSelectionEvent实例描述了这个选中事件的所影响的元素的范围以及选中是否仍在变化,如表13-8所示。当用户仍在修改被选中的元素,通过valueIsAdjusting设置为true,我们也许会希望延迟执行耗费资源的操作,例如绘制一个高分辨率的图形显示。
为了演示JList的选中,列表13-8中所示的程序向窗口添加了一个JTextArea来显示选中监听器的输出。监听器输出当前被选中的项的位置与值。
package swingstudy.ch13;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class SelectingJListSample {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
String labels[] = {"Chardonnay", "Sauvignon", "Riesling", "Cabernet",
"Zinfandel", "Merlot", "Pinot Noir", "Sauvignon Blanc", "Syrah", "Gewurztraminer"
};
JFrame frame = new JFrame("Selecting Jlist");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JList jlist = new JList(labels);
JScrollPane scrollPane1 = new JScrollPane(jlist);
frame.add(scrollPane1, BorderLayout.WEST);
final JTextArea textArea = new JTextArea();
textArea.setEditable(false);
JScrollPane scrollPane2 = new JScrollPane(textArea);
frame.add(scrollPane2, BorderLayout.CENTER);
ListSelectionListener listSelectionListener= new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println("First index: "+event.getFirstIndex());
pw.println(", Last idnex: "+event.getLastIndex());
boolean adjust = event.getValueIsAdjusting();
pw.println(", Adjusting? "+adjust);
if(!adjust) {
JList list = (JList)event.getSource();
int selections[] = list.getSelectedIndices();
Object selectionValues[] = list.getSelectedValues();
for(int i=0, n=selections.length; i
注意,如果我们知道JList处理单项选择模式中,我们可以使用selectedIndex或是selectedValue属性来获取当前被选中的项目。
图13-9显示了程序运行的结果。
列表13-8中的示例在没有快速更新时只输出当前选中的项(当isAdjusting报告false)时。否则,程序仅报告选中范围变化的起始与结束,以及调整状态。程序会检测JList的selectedIndices与selectedValues属性来获得选中项的有序列表。slectedIndices与slectedValues数组以相同的方式排序,所以数据模式中的特定元素显示在两个列表中的相同位置。
并没有特殊的选中事件用于处理列表中元素的双击。如果我们对双击感兴趣,那我们就要求助于AWT的MouseEvent/MouseListener对了。将下面的代码添加到列表13-8的程序中会向TextArea添加相应的文本用于响应双击事件。这里的关键方法是JList的public int locationToIndex(Point location),他会将屏幕坐标映射到列表元素。
import java.awt.event.*;
...
MouseListener mouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent mouseEvent) {
JList theList = (JList)mouseEvent.getSource();
if (mouseEvent.getClickCount() == 2) {
int index = theList.locationToIndex(mouseEvent.getPoint());
if (index >= 0) {
Object o = theList.getModel().getElementAt(index);
textArea.append("Double-clicked on: " + o.toString());
textArea.append(System.getProperty("line.separator"));
}
}
}
};
jlist.addMouseListener(mouseListener);
注意,JList类同时提供了一个public Point indexToLocation(int index)方法,这个方法会生成相反的行为。
手动选择JList事件
除了检测用户何时选择了列表中的项以外,我们也可以编程实现了列表项的选中与非选中。如果ListSelectionListener对象被叛逆到JList,当选中的项目集合被编程修改时他们也会得到相应的通知。可以使用下面的方法:
对于单个项目,public void setSelectedValue(Object element, boolean shouldScroll)选中与element匹配的第一项。如果element并不是前一次被选中的,已被选中的所有条目会首先取消选中。
对于一系列的项目,public void setSelectedInterval(int index0, int index1)选择一个包含的范围。
要向已选中的集合添加一系列的选中项目,使用public void addSelectedInterval(int index0, int index1)。
我们可以使用public void clearSelection()方法清除所有被选中的条目。
我们可以使用public void removeSelectedInterval(int index0, int index1)方法清除一个选中条目的范围。
显示多列
通常,当我们使用JList时,我们在单列中的显示其选项。尽管这是通常的使用方法,Swing JList控件为在多列中显示其选项提供了支持。借且于setLayoutOrientation()方法,我们可以设置JList方法来在水平列或是垂直列中的布局其单元。JList.VERTICAL是默认设置,其中所有的选项在一列中的显示。
要水平布局单元,在进入到下一行之前,使用值JList.HORIZONTAL_WRAP。例如,一个具有九个元素的列表可以以下面的方式显示:
要垂直布局单元,在进入下一列之前,使用值JList.VERTICAL_WRAP。例如,一个具有九个元素的列表可以以下面的方式显示:
设置JList的visibleRowCount属性来控制行数。否则,列表的宽度决定HORIZONTAL_WRAP的行数,而列表的高度决定VERTICAL_WRAP的列数。
图13-10显示了一个具有水平换行的JList,其中显示了一个3x3的网格。注意,他仍然支持多项选中模式。
13.2.7 自定义JList观感
每一个可安装的Swing观感都提供了不同的JList外观以及用于组件的默认的UIResource值设置集合。图13-11显示了JList在预安装的观感类型集合Motif,Windows以及Ocean下的外观。
JList的UIResource相关的属性集合显示在表13-9中。对于JList组件,有17个不同的属性。
类似于大多数的UIResource属性,大多数属性的名字都是自解释的。而List.timeFactor在这里需要解释一下。默认情况下,JList具有键盘选中的行为。当我们输入时,JList会查找到目前为止与我们的输入匹配的项。这是借助于public int getNextMatch(String prefix, int startIndex, Position.Bias bias)方法来实现的。“到目前为止”的量是由List.timeFactory设置来控制的。只要两次击键之间有延迟没有超出List.timeFactory指定的毫秒数(默认为1000),所输入的新键就会添加到前一个键序列中。一旦工厂超时,搜索字符串就会被重置。
13.2.8 创建双列表框
这一节所展示的示例创建了一个新的名为DualListBox的Swing组件。双列表框的基本目的就是创建两个选项列表:一个用于选取,而另一个构成结果集。当初始选项列表是可调整的时双列表框十分有用。尝试由一个跨越多个屏幕包含多个选项的JList中进行多项选择是一个麻烦的事情,特别是由于我们没有按下Shift或是Ctrl组合键时而恰好取消了我们已经选中的选项时。使用双列表模式,用户在每一个列表中选择选项并将其移动到第二个列表中。用户可以很容易的在两个列表之间进行滚动而不无需担心偶然取消了某了个选项。图13-12显示使用中的DualListBox的样子。
要使用这个自定义组件,通过调用构造函数DualListBox sdual = new DualListBox()来进行创建,然而使用setSourceElements()或addSourceLements()方法使用数据对其进行填充;每个方法都需要一个ListModel或是一个数组参数。add版本会补充已存在的选项,而set版本会首先清除已存在选项。当需要向组件查询用户选中了哪些选项时,我们可以使用destinationIterator()方法向已选中元素的Iterator进行查询。我们也许希望修改的属性如下所示:
源选项的标题(示例中的可用选项)
目标选项的标题(示例中我们的选项)
源或目标列单元渲染器
源或目标可见行数
源或是目标前景色或后景色
下面显示了这个新的DualListBox组件的完整源码。列表13-9包含了每一个类SortedListModel,他提供了一个已排序的ListModel。在其内部,他利用了TreeSet。
package swingstudy.ch13;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.AbstractListModel;
public class SortedListModel extends AbstractListModel {
SortedSet model;
public SortedListModel() {
model = new TreeSet();
}
@Override
public Object getElementAt(int index) {
// TODO Auto-generated method stub
return model.toArray()[index];
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return model.size();
}
public void add(Object element) {
if(model.add(element)) {
fireContentsChanged(this, 0, getSize());
}
}
public void addAll(Object elements[]) {
Collection c = Arrays.asList(elements);
model.addAll(c);
fireContentsChanged(this, 0, getSize());
}
public void clear() {
model.clear();
fireContentsChanged(this, 0, getSize());
}
public boolean contains(Object element) {
return model.contains(element);
}
public Object firstElement() {
return model.first();
}
public Iterator iterator() {
return model.iterator();
}
public Object lastElement() {
return model.last();
}
public boolean removeElement(Object element) {
boolean removed = model.remove(element);
if(removed) {
fireContentsChanged(this, 0, getSize());
}
return removed;
}
}
列表13-10显示了DualListBox的源码。其中包含的main()方法演示了该组件。
package swingstudy.ch13;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
public class DualListBox extends JPanel {
private static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
private static final String ADD_BUTTON_LABEL = "Add >>";
private static final String REMOVE_BUTTON_LABEL = "<< Remove";
private static final String DEFAULT_SOURCE_CHOICE_LABEL = "Advailable Choices";
private static final String DEFAULT_DEST_CHOICE_LABEL = "Your Choices";
private JLabel sourceLabel;
private JList sourceList;
private SortedListModel sourceListModel;
private JList destList;
private SortedListModel destListModel;
private JLabel destLabel;
private JButton addButton;
private JButton removeButton;
public DualListBox() {
initScreen();
}
public String getSourceChoicesTitle() {
return sourceLabel.getText();
}
public void setSourceChoicesTitle(String newValue) {
sourceLabel.setText(newValue);
}
public String getDestinationChoicesTitle() {
return destLabel.getText();
}
public void setDestinationChoicesTitle(String newValue) {
destLabel.setText(newValue);
}
public void clearSourceListModel() {
sourceListModel.clear();
}
public void clearDestinationListModel() {
destListModel.clear();
}
public void addSourceElements(ListModel newValue) {
fillListModel(sourceListModel, newValue);
}
public void setSourceElements(ListModel newValue) {
clearSourceListModel();
addSourceElements(newValue);
}
public void addDestinationElements(ListModel newValue) {
fillListModel(destListModel, newValue);
}
private void fillListModel(SortedListModel model, ListModel newValues) {
int size = newValues.getSize();
for(int i=0; i=0; i--) {
sourceListModel.removeElement(selected[i]);
}
sourceList.getSelectionModel().clearSelection();
}
private void clearDestinationSelected() {
Object selected[] = destList.getSelectedValues();
for(int i=selected.length-1; i>=0; --i) {
destListModel.removeElement(selected[i]);
}
destList.getSelectionModel().clearSelection();
}
private void initScreen() {
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridBagLayout());
sourceLabel = new JLabel(DEFAULT_SOURCE_CHOICE_LABEL);
sourceListModel = new SortedListModel();
sourceList = new JList(sourceListModel);
add(sourceLabel, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.CENTER,GridBagConstraints.NONE, EMPTY_INSETS, 0, 0));
add(new JScrollPane(sourceList), new GridBagConstraints(0,1,1,5,.5,1,GridBagConstraints.CENTER,GridBagConstraints.BOTH,EMPTY_INSETS,0,0));
addButton = new JButton(ADD_BUTTON_LABEL);
add(addButton, new GridBagConstraints(1,2,1,2,0,.25,GridBagConstraints.CENTER,GridBagConstraints.NONE,EMPTY_INSETS,0,0));
addButton.addActionListener(new AddListener());
removeButton = new JButton(REMOVE_BUTTON_LABEL);
add(removeButton, new GridBagConstraints(1,4,1,2,0,.25,GridBagConstraints.CENTER,GridBagConstraints.NONE, new Insets(0,5,0,5),0,0));
removeButton.addActionListener(new RemoveListener());
destLabel = new JLabel(DEFAULT_DEST_CHOICE_LABEL);
destListModel = new SortedListModel();
destList = new JList(destListModel);
add(destLabel, new GridBagConstraints(2,0,2,1,0,0,GridBagConstraints.CENTER,GridBagConstraints.NONE,EMPTY_INSETS,0,0));
add(new JScrollPane(destList), new GridBagConstraints(2,1,1,5,.5,1.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, EMPTY_INSETS,0,0));
}
private class AddListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object selected[] = sourceList.getSelectedValues();
addDestinationElements(selected);
clearSourceSelected();
}
}
private class RemoveListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object selected[] = destList.getSelectedValues();
addSourceElements(selected);
clearDestinationSelected();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Dual List Box Tester");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DualListBox dual = new DualListBox();
dual.addSourceElements(new String[] {"One", "Two", "Three"});
dual.addSourceElements(new String[] {"Four", "Five", "Six"});
dual.addSourceElements(new String[] {"Seven", "Eight", "Nigh"});
dual.addSourceElements(new String[] {"Ten", "Eleven", "Twele"});
dual.addSourceElements(new String[] {"Thirteen", "Fourteen", "Fifteen"});
dual.addSourceElements(new String[] {"Sixteen", "Seventeen", "Eighteen"});
dual.addSourceElements(new String[] {"Nineteen", "Twenty", "Thirty"});
frame.add(dual, BorderLayout.CENTER);
frame.setSize(400, 300);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
13.2.9 向列表项添加元素及工具提示
正如第4章所描述的,所有的Swing组件支持显示工具提示文本。通过调用组件的setToolTipText()方法 ,我们可以在组件上显示任意的文本字符串。在JList组件的情况下,单个的工具提示文本字符串也许并足够。我们也许希望在一个组件中的每一项上显示一个不同的提示。
显示元素级的提示需要一些工作。要在每一项上显示不同的工具提示文本,我们必须创建一个JList的子类。在这个子类中,我们必须手动向组件注册ToolTipManager。这通常是当我们调用setToolTipText()时为我们完成的。但是因为我们不会调用这个方法,我们必须手动通知管理器,如下所示:
ToolTipManager.sharedInstance().registerComponent(this);
在我们通知ToolTipManager之后,管理器会在鼠标滑过组件时通知组件。这允许我们覆盖public String getToolTipText(MouseEvent mouseEvent)方法来为鼠标点下的项提供相应的提示。使用某些Hashtable,HashMap或是Properties列表可以使得我们将鼠标滑过的项映射到相应的工具提示文本。
public String getToolTipText(MouseEvent event) {
Point p = event.getPoint();
int location = locationToIndex(p);
String key = (String)model.getElementAt(location);
String tip = tipProps.getProperty(key);
return tip;
}
图13-13显示了PropertiesList示例如何基于鼠标停留的元素演示各种工具提示。示例的完整源码显示在列表13-11中。
package swingstudy.ch13;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.Properties;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ToolTipManager;
public class PropertiesList extends JList {
SortedListModel model;
Properties tipProps;
public PropertiesList(Properties props) {
model = new SortedListModel();
setModel(model);
ToolTipManager.sharedInstance().registerComponent(this);
tipProps = props;
addProperties(props);
}
private void addProperties(Properties props) {
// Load
Enumeration names = props.propertyNames();
while(names.hasMoreElements()) {
model.add(names.nextElement());
}
}
public String getToolTipText(MouseEvent event) {
Point p = event.getPoint();
int location = locationToIndex(p);
String key = (String)model.getElementAt(location);
String tip = tipProps.getProperty(key);
return tip;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Custom Tip Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Properties props = System.getProperties();
PropertiesList list = new PropertiesList(props);
JScrollPane scrollPane = new JScrollPane(list);
frame.add(scrollPane);
frame.setSize(300, 300);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
你可能感兴趣的:(List Model Controls(二))
情绪觉察日记第37天
露露_e800
今天是家庭关系规划师的第二阶最后一天,慧萍老师帮我做了个案,帮我处理了埋在心底好多年的一份恐惧,并给了我深深的力量!这几天出来学习,爸妈过来婆家帮我带小孩,妈妈出于爱帮我收拾东西,并跟我先生和婆婆产生矛盾,妈妈觉得他们没有照顾好我…。今晚回家见到妈妈,我很欣赏她并赞扬她,妈妈说今晚要跟我睡我说好,当我们俩躺在床上准备睡觉的时候,我握着妈妈的手对她说:妈妈这几天辛苦你了,你看你多利害把我们的家收拾得
【iOS】MVC设计模式
Magnetic_h
ios mvc 设计模式 objective-c 学习 ui
MVC前言如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architecturalpattern),属于编程的方法论。MVC模式就是架构模式的一种。它是Apple官方推荐的App开发架构,也是一般开发者最先遇到、最经典的架构。MVC各层controller层Controller/ViewController/VC(控制器)负责协调Model和View,处理大部分逻辑它将数据从Mod
一百九十四章. 自相矛盾
巨木擎天
唉!就这么一夜,林子感觉就像过了很多天似的,先是回了阳间家里,遇到了那么多不可思议的事情儿。特别是小伙伴们,第二次与自己见面时,僵硬的表情和恐怖的气氛,让自己如坐针毡,打从心眼里难受!还有东子,他现在还好吗?有没有被人欺负?护城河里的小鱼小虾们,还都在吗?水不会真的干枯了吧?那对相亲相爱漂亮的太平鸟儿,还好吧!春天了,到了做窝、下蛋、喂养小鸟宝宝的时候了,希望它们都能够平安啊!虽然没有看见家人,也
10月|愿你的青春不负梦想-读书笔记-01
Tracy的小书斋
本书的作者是俞敏洪,大家都很熟悉他了吧。俞敏洪老师是我行业的领头羊吧,也是我事业上的偶像。本日摘录他书中第一章中的金句:『一个人如果什么目标都没有,就会浑浑噩噩,感觉生命中缺少能量。能给我们能量的,是对未来的期待。第一件事,我始终为了进步而努力。与其追寻全世界的骏马,不如种植丰美的草原,到时骏马自然会来。第二件事,我始终有阶段性的目标。什么东西能给我能量?答案是对未来的期待。』读到这里的时候,我便
C语言宏函数
南林yan
C语言 c语言
一、什么是宏函数?通过宏定义的函数是宏函数。如下,编译器在预处理阶段会将Add(x,y)替换为((x)*(y))#defineAdd(x,y)((x)*(y))#defineAdd(x,y)((x)*(y))intmain(){inta=10;intb=20;intd=10;intc=Add(a+d,b)*2;cout<
谢谢你们,爱你们!
鹿游儿
昨天家人去泡温泉,二个孩子也带着去,出发前一晚,匆匆下班,赶回家和孩子一起收拾。饭后,我拿出笔和本子(上次去澳门时做手帐的本子)写下了1\2\3\4\5\6\7\8\9,让后让小壹去思考,带什么出发去旅游呢?她在对应的数字旁边画上了,泳衣、泳圈、肖恩、内衣内裤、tapuy、拖鞋……画完后,就让她自己对着这个本子,将要带的,一一带上,没想到这次带的书还是这本《便便工厂》(晚上姑婆发照片过来,妹妹累得
爬山后遗症
璃绛
爬山,攀登,一步一步走向制高点,是一种挑战。成功抵达是一种无法言语的快乐,在山顶吹吹风,看看风景,这是从未有过的体验。然而,爬山一时爽,下山腿打颤,颠簸的路,一路向下走,腿部力量不够,走起来抖到不行,停不下来了!第二天必定腿疼,浑身酸痛,坐立难安!
《策划经理回忆录之二》
路基雅虎
话说三年变六年,飘了,飘了……眨眼,2013年5月,老吴回到了他的家乡——油城从新开启他的工作幻想症生涯。很庆幸,这是一家很有追求,同时敢于尝试的,且实力不容低调的新星房企——金源置业(前身泰源置业)更值得庆幸的是第一个盘就是油城十路的标杆之一:金源盛世。2013年5月,到2015年11月,两年的陪伴,迎来了一场大爆发。2000个筹,5万/筹,直接回笼1个亿!!!这……让我开始认真审视这座看似五线
《大清方方案》| 第二话
谁佐清欢
和珅究竟说了些什么?竟能令堂堂九五之尊龙颜失色!此处暂且按下不表;单说这位乾隆皇帝,果真不愧是康熙从小带过的,一旦决定了要做的事,便杀伐决断毫不含糊。他当即亲自拟旨,着令和珅为钦差大臣,全权负责处理方方事件,并钦赐尚方宝剑,遇急则三品以下官员可先斩后奏。和珅身负皇上重托,岂敢有半点怠慢,当夜即率领相关人等,马不停蹄杀奔江汉。这一路上,和珅的几位幕僚一直在商讨方方事件的处置方案。有位年轻幕僚建议快刀
【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数
广龙宇
一起学Rust # Rust设计模式 rust 设计模式 开发语言
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、使用借用类型作为参数二、格式化拼接字符串三、使用构造函数总结前言Rust不是传统的面向对象编程语言,它的所有特性,使其独一无二。因此,学习特定于Rust的设计模式是必要的。本系列文章为作者学习《Rust设计模式》的学习笔记以及自己的见解。因此,本系列文章的结构也与此书的结构相同(后续可能会调成结构),基本上分为三个部分
本周第二次约练
2cfbdfe28a51
中原焦点团队中24初26刘霞2021.12.3约练161次,分享第368天当事人虽然是带着问题来的,但是咨询过程中发现,她是经过自己不断地调整和努力才走到现在的,看到当事人的不容易,找到例外,发现资源,力量感也就随之而来。增强画面感,或者说重温,会给当事人带来更深刻的感受。
2022-07-08
保利学府里李楚怡1307022
——保利碧桂园学府里——童梦奇趣【科学实验室】「7.9-7.10」✏玩出大智慧约99-144㎡二期全新升级力作
WPF中的ComboBox控件几种数据绑定的方式
互联网打工人no1
wpf c#
一、用字典给ItemsSource赋值(此绑定用的地方很多,建议熟练掌握)在XMAL中:在CS文件中privatevoidBindData(){DictionarydicItem=newDictionary();dicItem.add(1,"北京");dicItem.add(2,"上海");dicItem.add(3,"广州");cmb_list.ItemsSource=dicItem;cmb_l
直抒《紫罗兰永恒花园外传》
雷姆的黑色童话
没看过《紫罗兰永恒花园》的我莫名的看完了《紫罗兰永恒花园外传》,又莫名的被故事中的姐妹之情狠狠地感动了的一把。感动何在:困苦中相依为命的姐妹二人被迫分离,用一个人的自由换取另一个人的幸福。之后,虽相隔不知几许依旧心心念念彼此牵挂。这种深深的姐妹情谊就是令我为之动容的所在。贝拉和泰勒分别影片开始,海天之间一个孩童凭栏眺望,手中拿着折旧的信纸。镜头一转,挑灯伏案的薇尔莉特正在打字机前奋笔疾书。这些片段
基于社交网络算法优化的二维最大熵图像分割
智能算法研学社(Jack旭)
智能优化算法应用 图像分割 算法 php 开发语言
智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码文章目录智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码1.前言2.二维最大熵阈值分割原理3.基于社交网络优化的多阈值分割4.算法结果:5.参考文献:6.Matlab代码摘要:本文介绍基于最大熵的图像分割,并且应用社交网络算法进行阈值寻优。1.前言阅读此文章前,请阅读《图像分割:直方图区域划分及信息统计介绍》htt
如果做到轻松在股市赚钱?只要坚持这三个原则。
履霜之人
大A股里向来就有七亏二平一赚的说法,能赚钱的都是少数人。否则股市就成了慈善机构,人人都有钱赚,谁还要上班?所以说亏钱是正常的,或者说是应该的。那么那些赚钱的人又是如何做到的呢?普通人能不能找到捷径去分一杯羹呢?方法是有的,但要做到需要你有极高的自律。第一,控制仓位,散户最大的问题是追涨杀跌,只要涨起来,就把钱往股票上砸,然后被套,隔天跌的受不了,又一刀切,全部割肉。来来回回间,遍体鳞伤。所以散户首
DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理
STU学生网页设计
网页设计 期末网页作业 html静态网页 html5期末大作业 网页设计 web大作业
️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程
特殊的拜年
飘雪的天堂
文/雪儿大年初一,家家户户没有了轰响的鞭炮声,大街上没有了人流涌动的喧闹,几乎看不到人影,变得冷冷清清。天刚亮不大会儿,村里的大喇叭响了起来:由于当前正值疾病高发期,流感流行的高峰期。同时,新型冠状病毒感染的肺炎进入第二波流行的上升期。为了自己和他人的健康安全着想,请大家尽量不要串门拜年,不要在街里走动。可以通过手机微信,视频,电话,信息拜年……今年的春节真是特别。禁止燃放鞭炮,烟花爆竹,禁止出村
398顺境,逆境
戴骁勇
2018.11.27周二雾霾最近儿子进入了一段顺境期,今天表现尤其不错。今天的数学测试成绩喜人,没有出现以往的计算错误,整个卷面书写工整,附加题也在规定时间内完成且做对。为迎接体育测试的锻炼有了质的飞跃。坐位体前屈成绩突飞猛进,估测成绩能达到12cm,这和上次测试的零分来比,简直是逆袭。儿子还在不断锻炼和提升,唯恐到时候掉链子。跑步姿势在我的调教下,逐渐正规起来,速度随之也有了提升。今晚测试的50
想明白这个问题,你才能写下去
文自拾
春节放假的时候,又有一天梦见她,第二天她冒着漫天大雪,傻傻地跑来见我。她说,见见傻傻的我,天很冷,心很暖。她回去后,我写了一篇文章,题目叫——从此梦中只有你。我们没在一起的很长一段时间里,她都在我的心底,一次次出现在我的梦里。我对她说,在一起之前,是胆小且闷骚,在一起之后,我变得不要脸了。不要脸的——去爱你。那文章没写完,火车上,给她看了。我有点小失望,花了好几个小时写,她分分钟就看完,很希望她逐
【JS】执行时长(100分) |思路参考+代码解析(C++)
l939035548
JS 算法 数据结构 c++
题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围
人工智能时代,程序员如何保持核心竞争力?
jmoych
人工智能
随着AIGC(如chatgpt、midjourney、claude等)大语言模型接二连三的涌现,AI辅助编程工具日益普及,程序员的工作方式正在发生深刻变革。有人担心AI可能取代部分编程工作,也有人认为AI是提高效率的得力助手。面对这一趋势,程序员应该如何应对?是专注于某个领域深耕细作,还是广泛学习以适应快速变化的技术环境?又或者,我们是否应该将重点转向AI无法轻易替代的软技能?让我们一起探讨程序员
其二
十八尾喵
你知道吗?图片发自App我今天知道了你有喜欢的人,不是我。心空空的,整个人都不是我的了。可,怎么办?还是要好好的活着,毕竟你喜欢的人,我不能杀,可是我可以杀其他喜欢你的人呀!也罢,此生无缘,来世再见。鱼干
libyuv之linux编译
jaronho
Linux linux 运维 服务器
文章目录一、下载源码二、编译源码三、注意事项1、银河麒麟系统(aarch64)(1)解决armv8-a+dotprod+i8mm指令集支持问题(2)解决armv9-a+sve2指令集支持问题一、下载源码到GitHub网站下载https://github.com/lemenkov/libyuv源码,或者用直接用git克隆到本地,如:gitclonehttps://github.com/lemenko
webpack图片等资源的处理
dmengmeng
需要的loaderfile-loader(让我们可以引入这些资源文件)url-loader(其实是file-loader的二次封装)img-loader(处理图片所需要的)在没有使用任何处理图片的loader之前,比如说css中用到了背景图片,那么最后打包会报错的,因为他没办法处理图片。其实你只想能够使用图片的话。只加一个file-loader就可以,打开网页能准确看到图片。{test:/\.(p
ARM中断处理过程
落汤老狗
嵌入式linux
一、前言本文主要以ARM体系结构下的中断处理为例,讲述整个中断处理过程中的硬件行为和软件动作。具体整个处理过程分成三个步骤来描述:1、第二章描述了中断处理的准备过程2、第三章描述了当发生中的时候,ARM硬件的行为3、第四章描述了ARM的中断进入过程4、第五章描述了ARM的中断退出过程本文涉及的代码来自3.14内核。另外,本文注意描述ARM指令集的内容,有些sourcecode为了简短一些,删除了T
如何成为段子手
欣雅阅读
我是一个尬聊大师,与朋友聊天经常把话题聊死,留我一个人在群里,望着自己打下的最后一句话无语凝噎。看到风趣幽默的朋友与人聊天,很是艳羡,觉得自己何时才能成为这样的段子手呢?一、段子是什么?“段子”一词在百度百科上的解释:本是相声中的一个艺术术语,指的是相声作品中一节或一段艺术内容。我的理解:段子就是一些搞笑的故事或者笑话。二、为什么要会说段子?不知道大家有没有这样的朋友,本来很无趣的聚会,只要有他参
Python爬虫解析工具之xpath使用详解
eqa11
python 爬虫 开发语言
文章目录Python爬虫解析工具之xpath使用详解一、引言二、环境准备1、插件安装2、依赖库安装三、xpath语法详解1、路径表达式2、通配符3、谓语4、常用函数四、xpath在Python代码中的使用1、文档树的创建2、使用xpath表达式3、获取元素内容和属性五、总结Python爬虫解析工具之xpath使用详解一、引言在Python爬虫开发中,数据提取是一个至关重要的环节。xpath作为一门
Redis系列:Geo 类型赋能亿级地图位置计算
Ly768768
redis bootstrap 数据库
1前言我们在篇深刻理解高性能Redis的本质的时候就介绍过Redis的几种基本数据结构,它是基于不同业务场景而设计的:动态字符串(REDIS_STRING):整数(REDIS_ENCODING_INT)、字符串(REDIS_ENCODING_RAW)双端列表(REDIS_ENCODING_LINKEDLIST)压缩列表(REDIS_ENCODING_ZIPLIST)跳跃表(REDIS_ENCODI
主题升华随机抽总结
木棉咕噜
昨天晚上在火山灿教练那里抽了主题升华最后一关。一共抽了两个故事,现总结如下。第一个故事是《并不是你想象的那样》。主题一:有时候,面对别人一些貌似不合常情的行为,不要轻易的指责他,也许背后有我们所不知道的原因。在这一个主题里面,刚开始的时候,我没有加上貌似二字。所以就没有改动之后这么精准。主题二:有时候我们对他人善意的行为,可能会给我们带来一些意外的回报。主题三:面对同样一件事,因为不同的人看待问题
戴尔笔记本win8系统改装win7系统
sophia天雪
win7 戴尔 改装系统 win8
戴尔win8 系统改装win7 系统详述
第一步:使用U盘制作虚拟光驱:
1)下载安装UltraISO:注册码可以在网上搜索。
2)启动UltraISO,点击“文件”—》“打开”按钮,打开已经准备好的ISO镜像文
BeanUtils.copyProperties使用笔记
bylijinnan
java
BeanUtils.copyProperties VS PropertyUtils.copyProperties
两者最大的区别是:
BeanUtils.copyProperties会进行类型转换,而PropertyUtils.copyProperties不会。
既然进行了类型转换,那BeanUtils.copyProperties的速度比不上PropertyUtils.copyProp
MyEclipse中文乱码问题
0624chenhong
MyEclipse
一、设置新建常见文件的默认编码格式,也就是文件保存的格式。
在不对MyEclipse进行设置的时候,默认保存文件的编码,一般跟简体中文操作系统(如windows2000,windowsXP)的编码一致,即GBK。
在简体中文系统下,ANSI 编码代表 GBK编码;在日文操作系统下,ANSI 编码代表 JIS 编码。
Window-->Preferences-->General -
发送邮件
不懂事的小屁孩
send email
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
动画合集
换个号韩国红果果
html css
动画 指一种样式变为另一种样式 keyframes应当始终定义0 100 过程
1 transition 制作鼠标滑过图片时的放大效果
css
.wrap{
width: 340px;height: 340px;
position: absolute;
top: 30%;
left: 20%;
overflow: hidden;
bor
网络最常见的攻击方式竟然是SQL注入
蓝儿唯美
sql注入
NTT研究表明,尽管SQL注入(SQLi)型攻击记录详尽且为人熟知,但目前网络应用程序仍然是SQLi攻击的重灾区。
信息安全和风险管理公司NTTCom Security发布的《2015全球智能威胁风险报告》表明,目前黑客攻击网络应用程序方式中最流行的,要数SQLi攻击。报告对去年发生的60亿攻击 行为进行分析,指出SQLi攻击是最常见的网络应用程序攻击方式。全球网络应用程序攻击中,SQLi攻击占
java笔记2
a-john
java
类的封装:
1,java中,对象就是一个封装体。封装是把对象的属性和服务结合成一个独立的的单位。并尽可能隐藏对象的内部细节(尤其是私有数据)
2,目的:使对象以外的部分不能随意存取对象的内部数据(如属性),从而使软件错误能够局部化,减少差错和排错的难度。
3,简单来说,“隐藏属性、方法或实现细节的过程”称为——封装。
4,封装的特性:
4.1设置
[Andengine]Error:can't creat bitmap form path “gfx/xxx.xxx”
aijuans
学习Android遇到的错误
最开始遇到这个错误是很早以前了,以前也没注意,只当是一个不理解的bug,因为所有的texture,textureregion都没有问题,但是就是提示错误。
昨天和美工要图片,本来是要背景透明的png格式,可是她却给了我一个jpg的。说明了之后她说没法改,因为没有png这个保存选项。
我就看了一下,和她要了psd的文件,还好我有一点
自己写的一个繁体到简体的转换程序
asialee
java 转换 繁体 filter 简体
今天调研一个任务,基于java的filter实现繁体到简体的转换,于是写了一个demo,给各位博友奉上,欢迎批评指正。
实现的思路是重载request的调取参数的几个方法,然后做下转换。
android意图和意图监听器技术
百合不是茶
android 显示意图 隐式意图 意图监听器
Intent是在activity之间传递数据;Intent的传递分为显示传递和隐式传递
显式意图:调用Intent.setComponent() 或 Intent.setClassName() 或 Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。
隐式意图;不指明调用的名称,根据设
spring3中新增的@value注解
bijian1013
java spring @Value
在spring 3.0中,可以通过使用@value,对一些如xxx.properties文件中的文件,进行键值对的注入,例子如下:
1.首先在applicationContext.xml中加入:
<beans xmlns="http://www.springframework.
Jboss启用CXF日志
sunjing
log jboss CXF
1. 在standalone.xml配置文件中添加system-properties:
<system-properties> <property name="org.apache.cxf.logging.enabled" value=&
【Hadoop三】Centos7_x86_64部署Hadoop集群之编译Hadoop源代码
bit1129
centos
编译必需的软件
Firebugs3.0.0
Maven3.2.3
Ant
JDK1.7.0_67
protobuf-2.5.0
Hadoop 2.5.2源码包
Firebugs3.0.0
http://sourceforge.jp/projects/sfnet_findbug
struts2验证框架的使用和扩展
白糖_
框架 xml bean struts 正则表达式
struts2能够对前台提交的表单数据进行输入有效性校验,通常有两种方式:
1、在Action类中通过validatexx方法验证,这种方式很简单,在此不再赘述;
2、通过编写xx-validation.xml文件执行表单验证,当用户提交表单请求后,struts会优先执行xml文件,如果校验不通过是不会让请求访问指定action的。
本文介绍一下struts2通过xml文件进行校验的方法并说
记录-感悟
braveCS
感悟
再翻翻以前写的感悟,有时会发现自己很幼稚,也会让自己找回初心。
2015-1-11 1. 能在工作之余学习感兴趣的东西已经很幸福了;
2. 要改变自己,不能这样一直在原来区域,要突破安全区舒适区,才能提高自己,往好的方面发展;
3. 多反省多思考;要会用工具,而不是变成工具的奴隶;
4. 一天内集中一个定长时间段看最新资讯和偏流式博
编程之美-数组中最长递增子序列
bylijinnan
编程之美
import java.util.Arrays;
import java.util.Random;
public class LongestAccendingSubSequence {
/**
* 编程之美 数组中最长递增子序列
* 书上的解法容易理解
* 另一方法书上没有提到的是,可以将数组排序(由小到大)得到新的数组,
* 然后求排序后的数组与原数
读书笔记5
chengxuyuancsdn
重复提交 struts2的token验证
1、重复提交
2、struts2的token验证
3、用response返回xml时的注意
1、重复提交
(1)应用场景
(1-1)点击提交按钮两次。
(1-2)使用浏览器后退按钮重复之前的操作,导致重复提交表单。
(1-3)刷新页面
(1-4)使用浏览器历史记录重复提交表单。
(1-5)浏览器重复的 HTTP 请求。
(2)解决方法
(2-1)禁掉提交按钮
(2-2)
[时空与探索]全球联合进行第二次费城实验的可能性
comsci
二次世界大战前后,由爱因斯坦参加的一次在海军舰艇上进行的物理学实验 -费城实验
至今给我们大家留下很多迷团.....
关于费城实验的详细过程,大家可以在网络上搜索一下,我这里就不详细描述了
在这里,我的意思是,现在
easy connect 之 ORA-12154: TNS: 无法解析指定的连接标识符
daizj
oracle ORA-12154
用easy connect连接出现“tns无法解析指定的连接标示符”的错误,如下:
C:\Users\Administrator>sqlplus username/pwd@192.168.0.5:1521/orcl
SQL*Plus: Release 10.2.0.1.0 – Production on 星期一 5月 21 18:16:20 2012
Copyright (c) 198
简单排序:归并排序
dieslrae
归并排序
public void mergeSort(int[] array){
int temp = array.length/2;
if(temp == 0){
return;
}
int[] a = new int[temp];
int
C语言中字符串的\0和空格
dcj3sjt126com
c
\0 为字符串结束符,比如说:
abcd (空格)cdefg;
存入数组时,空格作为一个字符占有一个字节的空间,我们
解决Composer国内速度慢的办法
dcj3sjt126com
Composer
用法:
有两种方式启用本镜像服务:
1 将以下配置信息添加到 Composer 的配置文件 config.json 中(系统全局配置)。见“例1”
2 将以下配置信息添加到你的项目的 composer.json 文件中(针对单个项目配置)。见“例2”
为了避免安装包的时候都要执行两次查询,切记要添加禁用 packagist 的设置,如下 1 2 3 4 5
高效可伸缩的结果缓存
shuizhaosi888
高效可伸缩的结果缓存
/**
* 要执行的算法,返回结果v
*/
public interface Computable<A, V> {
public V comput(final A arg);
}
/**
* 用于缓存数据
*/
public class Memoizer<A, V> implements Computable<A,
三点定位的算法
haoningabc
c 算法
三点定位,
已知a,b,c三个顶点的x,y坐标
和三个点都z坐标的距离,la,lb,lc
求z点的坐标
原理就是围绕a,b,c 三个点画圆,三个圆焦点的部分就是所求
但是,由于三个点的距离可能不准,不一定会有结果,
所以是三个圆环的焦点,环的宽度开始为0,没有取到则加1
运行
gcc -lm test.c
test.c代码如下
#include "stdi
epoll使用详解
jimmee
c linux 服务端编程 epoll
epoll - I/O event notification facility在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linu
Hibernate对Enum的映射的基本使用方法
linzx0212
enum Hibernate
枚举
/**
* 性别枚举
*/
public enum Gender {
MALE(0), FEMALE(1), OTHER(2);
private Gender(int i) {
this.i = i;
}
private int i;
public int getI
第10章 高级事件(下)
onestopweb
事件
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/
孙子兵法
roadrunners
孙子 兵法
始计第一
孙子曰:
兵者,国之大事,死生之地,存亡之道,不可不察也。
故经之以五事,校之以计,而索其情:一曰道,二曰天,三曰地,四曰将,五
曰法。道者,令民于上同意,可与之死,可与之生,而不危也;天者,阴阳、寒暑
、时制也;地者,远近、险易、广狭、死生也;将者,智、信、仁、勇、严也;法
者,曲制、官道、主用也。凡此五者,将莫不闻,知之者胜,不知之者不胜。故校
之以计,而索其情,曰
MySQL双向复制
tomcat_oracle
mysql
本文包括:
主机配置
从机配置
建立主-从复制
建立双向复制
背景
按照以下简单的步骤:
参考一下:
在机器A配置主机(192.168.1.30)
在机器B配置从机(192.168.1.29)
我们可以使用下面的步骤来实现这一点
步骤1:机器A设置主机
在主机中打开配置文件 ,
zoj 3822 Domination(dp)
阿尔萨斯
Mina
题目链接:zoj 3822 Domination
题目大意:给定一个N∗M的棋盘,每次任选一个位置放置一枚棋子,直到每行每列上都至少有一枚棋子,问放置棋子个数的期望。
解题思路:大白书上概率那一张有一道类似的题目,但是因为时间比较久了,还是稍微想了一下。dp[i][j][k]表示i行j列上均有至少一枚棋子,并且消耗k步的概率(k≤i∗j),因为放置在i+1~n上等价与放在i+1行上,同理