可以把圖片加入到JLabel里面;JLabel有這樣一個(gè)方法 JLabel(String text, int horizontalAlignment) 創(chuàng)建具有指定文本和水平對(duì)齊方式的 JLabel 實(shí)例。
廈門ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!
好像和另外一個(gè)一樣,貼一下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GoodLucky extends JFrame implements ActionListener{
JTextField tf = new JTextField(); //實(shí)例化一個(gè)文本域
//設(shè)置兩個(gè)按鈕
JButton b1 = new JButton("開始");
JButton b2 = new JButton("停止");
boolean isGo = false;
//構(gòu)造函數(shù)
public GoodLucky(){
b1.setActionCommand("start");//在開始按鈕上設(shè)置一個(gè)動(dòng)作監(jiān)聽 start
JPanel p = new JPanel(); //實(shí)例化一個(gè)可視化容器
//將兩個(gè)按鈕添加到可視化容器上面,用add方法
p.add(b1);
p.add(b2);
//在兩個(gè)按鈕上增加監(jiān)聽的屬性,自動(dòng)調(diào)用下面的監(jiān)聽處理方法actionPerformed(ActionEvent e),如果要代碼有更好的可讀性,可用內(nèi)部類實(shí)現(xiàn)動(dòng)作
//監(jiān)聽處理。
b1.addActionListener(this);
b2.addActionListener(this);
//將停止按鈕設(shè)置為不可編輯(即不可按的狀態(tài))
b2.setEnabled(false);
this.getContentPane().add(tf,"North"); //將上面的文本域放在面板的北方,也就是上面(上北下南左西右東)
this.getContentPane().add(p,"South"); //將可視化容器pannel放在南邊,也就是下面
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設(shè)置用戶在此窗體上發(fā)起 "close" 時(shí)默認(rèn)執(zhí)行的操作,參數(shù)EXIT_ON_CLOSE是使用 System exit 方法退出應(yīng)用程序。僅在應(yīng)用程序中使用
this.setSize(300,200); //設(shè)置面板大小,寬和高
this.setLocation(300,300); //設(shè)置面板剛開始的出現(xiàn)的位置
Cursor cu = new Cursor(Cursor.HAND_CURSOR); //用指定名稱創(chuàng)建一個(gè)新的定制光標(biāo)對(duì)象,參數(shù)表示手狀光標(biāo)類型
this.setCursor(cu); //為指定的光標(biāo)設(shè)置光標(biāo)圖像,即設(shè)置光標(biāo)圖像為上面所創(chuàng)建的手狀光標(biāo)類型
this.setVisible(true); //將面板可視化設(shè)置為true,即可視,如果為false,即程序運(yùn)行時(shí)面板會(huì)隱藏
tf.setText("welcome you! "); //設(shè)置面板的標(biāo)題為歡迎
this.go(); //調(diào)用go方法
}
public void go(){
while(true){ //這里是死循環(huán),也就是說(shuō)用戶不點(diǎn)擊停止按鈕的話他一直循環(huán)出現(xiàn)隨機(jī)數(shù),直到用戶點(diǎn)擊停止按鈕循環(huán)才能推出,具體流程在actionPerformed方法中控制。
if(isGo == true){ //上面所定義的isGo的初始值為false,所以程序第一次到此會(huì)跳過
String s = ""; //設(shè)置空字符串
for(int j = 1; j = 7;j++){ //產(chǎn)生7個(gè)隨機(jī)數(shù)
int i = (int)(Math.random() * 36) + 1;//每個(gè)隨機(jī)數(shù)產(chǎn)生方式,這里定義靈活,可以自由定義隨機(jī)數(shù)產(chǎn)生的方式
if(i 10){
s = s + " 0" + i; //如果產(chǎn)生的隨機(jī)數(shù)小于10的話做處理:這里就牽扯到一個(gè)重要的概念,簡(jiǎn)單敘述一下:
/*
當(dāng)一個(gè)字符串與一個(gè)整型數(shù)項(xiàng)相加的意思是連接,上面的s = s + " 0" + i的意思是字符串s鏈接0再連接整型i值,而不會(huì)導(dǎo)致0和整型的i相加,
產(chǎn)生的效果為s0i,由于s為空字符串(上面定義過的),所以當(dāng)i小于零時(shí),在個(gè)位數(shù)前面加上0,比如產(chǎn)生的隨機(jī)數(shù)i為7的話,顯示效果為 07.
*/
}else{
s = s + " " + i; //如果產(chǎn)生的隨機(jī)數(shù)比10打的話,那么加上空格顯示,即數(shù)字和數(shù)字之間有個(gè)空格
}
//以上循環(huán)循環(huán)七次,以保證能出現(xiàn)7個(gè)隨機(jī)數(shù)
}
tf.setText(s); //將產(chǎn)生的隨機(jī)數(shù)全部顯示在文本域上,用文本域?qū)ο髏f調(diào)用它的設(shè)置文本的方法setText(String)實(shí)現(xiàn)。
}
//以下為線程延遲
try{
Thread.sleep(10); //線程類同步方法sleep,睡眠方法,括號(hào)里的單位為ms。
}catch(java.lang.InterruptedException e){
e.printStackTrace(); //異常捕獲,不用多說(shuō)。
}
}
}
//以下是上面設(shè)置的事件監(jiān)聽的具體處理辦法,即監(jiān)聽時(shí)間處理方法,自動(dòng)調(diào)用
public void actionPerformed(ActionEvent e){ //傳入一個(gè)動(dòng)作事件的參數(shù)e
String s = e.getActionCommand(); //設(shè)置字符串s來(lái)存儲(chǔ)獲得動(dòng)作監(jiān)聽,上面的start
/*
以下這個(gè)條件語(yǔ)句塊的作用為:用戶點(diǎn)擊開始后(捕獲start,用方法getActionCommand()),將命令觸發(fā)設(shè)置為true,從而執(zhí)行上面的go方法中的循環(huán)體(因?yàn)檠h(huán)體中要求isGo參數(shù)為true,而初始為false)。
執(zhí)行循環(huán)快產(chǎn)生隨機(jī)數(shù),并將開始按鈕不可編輯化,而用戶只可以使用停止按鈕去停止。如果用戶按下停止時(shí),也就是沒有傳入?yún)?shù)“start”的時(shí)候,
執(zhí)行else語(yǔ)句塊中的語(yǔ)句,isGo設(shè)置為false,將不執(zhí)行上面go中的循環(huán)語(yǔ)句塊,從而停止產(chǎn)生隨機(jī)數(shù),并顯示,并且把開始按鈕設(shè)置為可用,而把
停止按鈕設(shè)置為不可用,等待用戶按下開始再去開始新一輪循環(huán)產(chǎn)生隨機(jī)數(shù)。
*/
if(s.equals("start")){ //如果捕獲到start,也就是用戶觸發(fā)了動(dòng)作監(jiān)聽器,那么下面處理
isGo = true; //設(shè)置isGo為true
b1.setEnabled(false); //將開始按鈕設(shè)置為不可用
b2.setEnabled(true); //將停止按鈕設(shè)置為可用
}else{
isGo = false; //將isGo設(shè)置為false,isGo為循環(huán)標(biāo)志位
b2.setEnabled(false); //設(shè)置停止按鈕為不可用(注意看是b2,b2是停止按鈕)
b1.setEnabled(true); //設(shè)置開始按鈕為可用
}
}
public static void main(String[] args){
new GoodLucky(); //產(chǎn)生類的實(shí)例,執(zhí)行方法
}
}
一:幾何距(Geometric
Moments)知識(shí)與質(zhì)心尋找原理
1.
Image
Moments是圖像處理中非常有用的算法,可以用來(lái)計(jì)算區(qū)域圖像的質(zhì)心,方向等幾何特性,同時(shí)Mpq的高階具有旋轉(zhuǎn)不變性,可以用來(lái)實(shí)現(xiàn)圖像比較分類,正是因?yàn)镸oments有這些特性,很多手繪油畫效果也會(huì)基于該算法來(lái)模擬實(shí)現(xiàn)。它的數(shù)學(xué)表達(dá)為:
它的低階M00,M01,
M10可以用來(lái)計(jì)算質(zhì)心,中心化以后M11,M02,M20可以用來(lái)計(jì)算區(qū)域的方向/角度
2.
什么是質(zhì)心
就是通過該點(diǎn),區(qū)域達(dá)到一種質(zhì)量上的平衡狀態(tài),可能物理學(xué)上講的比較多,簡(jiǎn)單點(diǎn)的說(shuō)就是規(guī)則幾何物體的中心,不規(guī)則的可以通過掛繩子的方法來(lái)尋找。
二:算法流程
1.
輸入圖像轉(zhuǎn)換為二值圖像
2.
通過連通組件標(biāo)記算法找到所有的連通區(qū)域,并分別標(biāo)記
3.
對(duì)每個(gè)連通區(qū)域運(yùn)用計(jì)算幾何距算法得到質(zhì)心
4.
用不同顏色繪制連通區(qū)域與質(zhì)心,輸出處理后圖像
三:算法效果
左邊為原圖,
右邊藍(lán)色為連通組件標(biāo)記算法處理以后結(jié)果,白色點(diǎn)為質(zhì)心
四:關(guān)鍵代碼解析
1.
計(jì)算幾何距算法代碼
doublem00
=
moments(pixels,
width,
height,
0,
0);
doublexCr
=
moments(pixels,
width,
height,
1,
0)
/
m00;//
row
doubleyCr
=
moments(pixels,
width,
height,
0,
1)
/
m00;//
column
return
new
double[]{xCr,
yCr};
public class PhotoFrame extends JFrame
{
private static final long serialVersionUID = -2216276219179107707L;
private Container con;
private MousePanel zPanel;
private JScrollPane imgSp;
private JPanel btnPanel;
private String imageDir;
private String currImg;//文件名,不包含目錄
private int currIndex;//當(dāng)前圖片索引
ArrayListString imgList;//所有圖片的絕對(duì)路徑
public void writeCropImg() throws IOException
{
BufferedImage sourceImage = (BufferedImage) zPanel.getImg();
Image croppedImage;
ImageFilter cropFilter;
int x = zPanel.getPointX()-25;
int y = zPanel.getPointY()-25;
//四個(gè)參數(shù)分別為圖像起點(diǎn)坐標(biāo)和寬高,即CropImageFilter(int x,int y,int width,int height),詳細(xì)情況請(qǐng)參考API
//指定要裁剪的的文件的寬度和高度,以及起始坐標(biāo)
cropFilter =new CropImageFilter(x,y,50,50);
//生成圖片
croppedImage= Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(sourceImage.getSource(),cropFilter));
//獲取創(chuàng)建后的圖片的高度
int h1=croppedImage.getHeight(null);
int w1=croppedImage.getWidth(null);
BufferedImage bi=new BufferedImage(w1,h1,BufferedImage.TYPE_INT_RGB);
Graphics g=bi.getGraphics();
//在畫圖的時(shí)候可以設(shè)置背景色
g.drawImage(croppedImage,0,0,Color.white,null);
String dir = imageDir+"_crops";
//創(chuàng)建文件輸出流
FileOutputStream fos=new FileOutputStream(new File(dir+"/"+currImg));
//將創(chuàng)建的圖片寫入到輸出流
ImageIO.write(bi, "png", fos);
fos.close();
}
private void showNext()
{
updateCurrName();
zPanel.setImagePath(imgList.get(currIndex));
currIndex++;
}
private void updateCurrName()
{
String path = imgList.get(currIndex);
int index = path.lastIndexOf('/');
currImg = path.substring(index);
}
private class nextHandler implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
showNext();
}
}
private class openDirHandler implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//設(shè)置只能選擇目錄
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
imageDir =chooser.getSelectedFile().getPath();
imgList = FileTool.refreshFileList(imageDir);
currIndex = 0;
showNext();
//System.out.println ( "你選擇的目錄是:" + selectPath );
//你選擇的目錄是:/home/linger/imdata/collar
}
}
}
private void savePointAndImg()
{
try
{
String dir = imageDir+"_points";
int x = zPanel.getPointX();
int y = zPanel.getPointY();
//打開文件
File f=new File(dir+"/");
if(!f.exists())
{
f.mkdir();
}
f=new File(dir+"/"+currImg);
if(!f.exists())
{
f.createNewFile();
}
FileOutputStream fos=new FileOutputStream(f);
OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
BufferedWriter bw=new BufferedWriter(osw);
//寫入文件
bw.write(x+","+y);
//關(guān)閉文件
bw.close();
osw.close();
fos.close();
writeCropImg();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
private class savePointHandler implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
savePointAndImg();
}
}
private class openImageHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG PNG Images", "jpg", "png");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
File file = chooser.getSelectedFile();
imageDir = file.getParent();
imgList = FileTool.refreshFileList(imageDir);
currImg = file.getName();//文件名,不包含路徑
// System.out.println();
String path = file.getAbsolutePath();
currIndex = imgList.indexOf(path);
zPanel.setImagePath(path);
currIndex++;
//內(nèi)部類訪問外部類,可以直接訪問的啊
}
}
}
private PhotoFrame()
{
con = getContentPane();
con.setLayout(new GridLayout(2,2));
zPanel = new MousePanel();
//zPanel.setImagePath("/home/linger/17820d01");//綁定圖片
//zPanel.setPreferredSize(new Dimension(zPanel.getImgWidth(), zPanel.getImgHeight()));
imgSp = new JScrollPane();
imgSp.setPreferredSize(new Dimension(zPanel.getImgWidth(), zPanel.getImgHeight()));
imgSp.setViewportView(zPanel);
imgSp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
imgSp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
//con.add(imgSp, BorderLayout.CENTER);
con.add(imgSp);
btnPanel = new JPanel();
btnPanel.setLayout(new FlowLayout());
btnPanel.setSize(300,100);
JButton button = new JButton("打開圖片");
button.setSize(100, 50);
btnPanel.add(button);
button.addActionListener(new openImageHandler());
button = new JButton("保存坐標(biāo)");
button.setSize(100, 50);
btnPanel.add(button);
button.addActionListener(new savePointHandler());
button = new JButton("打開目錄");
button.setSize(100, 50);
btnPanel.add(button);
button.addActionListener(new openDirHandler());
button = new JButton("下一張");
button.setSize(100, 50);
btnPanel.add(button);
button.addActionListener(new nextHandler());
con.add(btnPanel);
zPanel.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
if(e.getClickCount() == 2)
{
savePointAndImg();
showNext();
}
}
});
finalSetting();
}
private void finalSetting()
{
setTitle("標(biāo)注工具");
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenHeight = screenSize.height;
int screenWidth = screenSize.width;
int frameH = getHeight();
int frameW = getWidth();
setLocation((screenWidth - frameW) / 2 - 250,
(screenHeight - frameH) / 2 - 250);
setSize(800, 600);
//setSize(zPanel.getImgWidth()+10, zPanel.getImgHeight()+10);
//setPreferredSize(new Dimension(zPanel.getImgWidth()+100, zPanel.getImgHeight()+100));
//pack();
setVisible(true);
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
new PhotoFrame();
}
}
一個(gè)簡(jiǎn)單的表格,就顯示兩行數(shù)據(jù)
package cn.mff.mvc.view.studentdialog;
import java.awt.Color;
import javax.swing.*;
import javax.swing.JTable;
import javax.swing.table.*;
//import oracle.jdeveloper.layout.OverlayLayout2;
//一個(gè)測(cè)試,看JTable怎么用
public class TableTest extends JFrame{
private JTable table;
private JScrollPane scrollPane;
private JTableHeader tableh;
public TableTest(){
super("表格顯示");
//設(shè)置JTable的title和content
Object[][] content = {{"mafeifei","12","f","24"},{"wangran","4","f","20"}};
String[] title ={"name","number","sex","age"};
table = new JTable(content,title);
//設(shè)置背景色
table.setBackground(new Color(230, 230, 230));
//jtable沒有選中的文字顏色
table.setForeground(new Color(0, 0, 0));
//設(shè)置邊線線條
table.setGridColor(Color.CYAN);
tableh = table.getTableHeader();
//設(shè)置表頭背景色
tableh.setBackground(Color.GREEN);
scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
}
public static void main(String[] args){
TableTest test = new TableTest();
test.setSize(400,300);
test.setDefaultCloseOperation(EXIT_ON_CLOSE);
test.setVisible(true);
}
}