您的位置:首页 > 其它

技术点整理与JTextField的一些扩展

2013-01-20 09:43 363 查看
以前做插件用的几乎都是SWT,最近由于项目原因,用起了Swing,记得上次使用Swing还是在实习的时候。

以下列举最近涉及的一些技术点,记录供以后参考用。

1. 仅启动一个应用程序实例 (利用文件锁)。

String filePath = System.getProperty("user.dir") + File.separator + ".lock";
File lf = new File(filePath);
if (!lf.exists()) {
lf.createNewFile();
}
FileLock lock = new FileOutputStream(filePath).getChannel().tryLock();
if (lock == null) {
JOptionPane.showMessageDialog(null, "app is running", "Info", JOptionPane.INFORMATION_MESSAGE);
}else {
JFrame frame = new JFrame();
frame.setVisible(true);
}


2. 利用NinePatch来拉伸图片。
Ref: /article/5440600.html

3. 利用log4j每日生成一个日志,待日志超出指定数目时进行压缩。
log4j.rootLogger=DEBUG, file
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern='_'yyyy-MM-dd
log4j.appender.file.File=app.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %p %m

生成的日志格式如:app.log_20121201
达到指定值(thresold>=30)后,日志被压缩,如:app_20121201_20121230.zip
public void zip(String path, final String matchFileName, int thresold) {
List<String> li = new ArrayList<String>(50);
File logFolder = new File(path);
String[] fs = logFolder.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if(name.matches(matchFileName)) {
return true;
}
return false;
}
});
if(fs.length < thresold) { //default : 30
return;
}

for(int i=0; i<fs.length; i++) {
li.add(fs[i]);
}
Collections.sort(li);

int size = li.size();
String name = li.get(0).substring(0, li.get(0).lastIndexOf("."));
String startDate = li.get(0).substring(li.get(0).lastIndexOf("_")+1);
String endDate = li.get(size-1).substring(li.get(size-1).lastIndexOf("_")+1);
String zipFileName = name + "_" + startDate + "_" + endDate + ".zip";
logger.info("create " + zipFileName);

//zip log files
FileOutputStream fos = null;
ZipOutputStream zos = null;
try {
fos = new FileOutputStream(path + File.separator + zipFileName);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
for (int idx=0; idx<size; idx++) {
File f = new File(path + File.separator + li.get(idx));
zos.putNextEntry(new ZipEntry(li.get(idx)));
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(f);
while (fis.read(buffer) != -1) {
zos.write(buffer);
}
fis.close();
f.delete();
}
}catch(IOException e) {
logger.error("zip logs error.", e);
}finally {
try {
if(zos != null) {
zos.closeEntry();
zos.close();
}
if(fos != null) {
fos.close();
}
} catch (IOException e) {
logger.error("close outputstream error.", e);
}
}
logger.info("zip completed : " + path + File.separator + zipFileName);
}


4. 更新UI的操作需要放入EDT执行。

5. JFreeChart创建灰度直方图和线性图。
可参看JFreeChart官方Demo中HistogramDemo1.java和XYSeriesDemo1.java。
若图中不能正常显示中文,可通过以下方法解决。
Font font = new Font("宋体", Font.PLAIN, 10);
chart.getTitle().setFont(font); //设置图的标题字体
ValueAxis xAxis = plot.getDomainAxis();
ValueAxis yAxis = plot.getRangeAxis();
xAxis.setTickLabelFont(font); //设置X轴上的文字字体
xAxis.setLabelFont(font); //设置X轴的标题字体
yAxis.setTickLabelFont(font); //设置Y轴上的文字字体
yAxis.setLabelFont(font); //设置Y轴的标题字体


6. 求图像中间区域的均值,如中间256*256区域

public static double mean256(short[] imgContentData, int w, int h) {
double mean256 = 0;
if(w <= 256 || h <=256) {
throw new Exception(“width or height error.”);
}else {
int size = 256;
long sum = 0;
int offsetY = h/2 - size/2;
int offsetX = w/2 - size/2;
for(int row=0; row<size; row++) {
for(int col=0; col<size; col++) {
sum += imgContentData[w*offsetY + offsetX + col] & 0xFFFF;
}
offsetY = offsetY + 1;
}
mean256 = sum/((double)(size*size));
}
return mean256;
}


7. 绘制垂直渐变和水平渐变的JPanel。

垂直渐变:
class GradientPanelV extends JPanel {
int x,y,w,h;
Color startColor,endColor;
public GradientPanelV (int x, int y, int width, int hight, Color startColor, Color endColor) {
this.x = x;
this.y = y;
this.w = width;
this.h = hight;
this.startColor = startColor;
this.endColor = endColor;
}

protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;

GradientPaint grPaint = new GradientPaint(
(float)x, (float)y, startColor,
(float)x, (float)h, endColor);
g2.setPaint(grPaint);
g2.fillRect(x, y, w, h);
g2.setPaint(null);
}
}

水平渐变
class GradientPanelH extends JPanel {
//~略,同上~
protected void paintComponent(Graphics g) {
  		//~略,同上~
GradientPaint grPaint = new GradientPaint((float)x, (float)y, startColor, (float)w, (float)y, endColor);
//~略,同上~
}
}


8. JtextPane中插入文本和icon后,icon与文本底部未对齐。
解决办法是调用icon的setAlignmentY方法,然后调整传入参数的大小即可。
如setAlignmentY(0.75),表示icon的75%在基线上方,25%在基线下方。

9.
用图片表示Jbutton按钮。如

,按下按钮后效果


实现代码如下:

btn.setBorder(null);
btn.setContentAreaFilled(false);
btn.setIcon(new ImageIcon(this.class.getResource("next.png")));


10. 根据当前所用的字体来获取文本框(JTextField)的高和宽。

int columns = 15;
JTextField tf = new JTextField(columns);
FontMetrics metrics = tf.getFontMetrics(font);
int columnWidth = metricsCB.charWidth('m');
Insets insets = tf.getInsets();
int width = columns * columnWidth + insets.left + insets.right;
int height = metrics.getHeight() + insets.top + insets.bottom;


JTextField的一些扩展应用
1. 使文本框仅能输入浮点数。
JTextField tf = new JTextField(15);
tf.setDocument(new PlainDocument() {
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (str == null) {
return;
}
String oldString = getText(0, getLength()); //插入新字符前的字符串
String newString = oldString.substring(0, offs) + str + oldString.substring(offs); //插入新字符后的字符串
try {
Float.parseFloat(newString);
super.insertString(offs, str, a);
} catch (NumberFormatException e){
}
}
});
tf.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
//向文本框输入文字,会触发此方法
}
public void removeUpdate(DocumentEvent e) {
//删除本框中文字,会触发此方法
}
});


2. 点击文本框,弹出列表。

有这样一个需求:
点击文本框,列表弹出。文本框中按下回车或Esc,列表消失。
若在单击列表中某一项,该项内容会设置到文本框中。
若双击某一项,该项内容会设置到文本框中,而且列表也会关闭。如图:



点击这里下载。
同理,点击文本框也可弹出树和表格等更复杂的控件。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: