Apache Derby, an Apache DB subproject, is an open source relational database implemented entirely in Java and available under the Apache License, Version 2.0.

Apache Derby,是Apache数据库子项目,是开放源代码数据库,纯粹用java实现,基于Apache License 2发行。

Sun公司的实现版本叫JavaDB

Java DB is Sun's supported distribution of the open source Apache Derby 100% Java technology database. It is fully transactional, secure, easy-to-use, standards-based — SQL, JDBC API, and Java EE — yet small, only 2.5 MB.

这个数据库只有2.5M大。

下载安装完JavaDB后,如何使用呢。只要在classpath路径里包含derby.jar就可以了。

Installing Java DB for development requires only that you make the derby.jar file part of your application classpath. It's that simple. You can set the CLASSPATH variable of your Solaris, Linux, Windows, or other host environment to include the JAR file, or you can include the file as part of your command-line options when compiling or running

Using Java DB in Desktop Applications

 
By John O'Conner, March 2006  

Articles Index

Sun Microsystems recently announced that it is distributing and supporting Java DB based on the 100 percent Java technology, open-source Apache Derby database. Derby was previously available under its earlier name, Cloudscape, from its former owners: Cloudscape, Informix, and IBM. IBM donated the Derby product source code to the Apache Foundation as an open-source project. Sun, IBM, other companies, and individuals have been actively involved in development of the relational database as part of the Apache Derby community. Sun distributes Java DB in many of its products, including the Sun Java Enterprise System and the Sun Java System Application Server. The NetBeans integrated development environment (IDE) 5.0 also supports Java DB.

Java DB is lightweight at 2 megabytes and embeddable within desktop Java technology applications. Desktop applications can now access powerful database storage with triggers, stored procedures, and support for SQL, Java DataBase Connectivity (JDBC) software, and Java Platform, Enterprise Edition (Java EE, formerly referred to as J2EE), all embedded within the same Java virtual machine (JVM).*

This article describes how to download, install, integrate, and deploy Java DB within desktop Java technology applications. A demo application called Address Book demonstrates how to work with Java DB as an embedded database.

Contents
Creating the Address Book Demo
Installing Java DB
Integrating Java DB With NetBeans IDE 5.0
Loading the Database Driver
Connecting to the Java DB Database
Creating the Database
Using the Database
Deploying Your Application
Summary
Creating the Address Book Demo

The Address Book demo uses Java DB to store address information. This demo stores names, phone numbers, email addresses, and postal addresses. It allows you to create new address entries and to save, edit, and delete them. The application creates its database in the user's home directory within an .addressbook subdirectory. The database is embedded with the application, so there is no need to set up or manage a separate server or system. To deploy this embedded database application, we need only the application JAR file and the database library JAR file. Figure 1 shows the demo's user interface (UI).

Figure 1: Address Book uses Java DB as an embedded database.
Figure 1: Address Book uses Java DB as an embedded database.

Address Book's main frame window is an AddressFrame class that extends a Java Foundation Classes/Swing (JFC/Swing) JFrame. The AddressFrame is a container for other graphical components and also acts as a controller by handling various events generated by the child components. The child components are JPanel subclasses, each with a different responsibility:

  • AddressPanel represents an address record. It also provides the UI for editing existing records and creating new records. It contains text fields for all the major properties of an Address object.
  • AddressActionPanel provides buttons for all the major use cases that the application supports. This panel generates events that AddressFrame must handle. For example, when the user clicks Save, this panel generates an event. AddressFrame listens to and handles all important events from this panel.
  • AddressListPanel provides a scrollable list of names on the far left of the AddressFrame. The list holds ListEntry objects. A ListEntry stores a database record's unique identifier. The record identifier (ID) allows the application to retrieve an entire record's contents into the AddressPanel.

The application uses a Data Access Object (DAO) to isolate the database-specific code. The DAO encapsulates database connections and statements. A DAO is a useful design pattern that allows loose coupling between an application and the underlying persistence-storage mechanism. The application's AddressDao class is an example of a DAO. When the AddressFrame edits, saves, or deletes an Address object, it always uses an instance of the AddressDao class. Although the Address Book application uses Java DB, you could change it to use an entirely different database just by modifying this one class.

Installing Java DB

The easiest way to get Java DB is to download a copy from the Sun Developer Network's Java DB site. The binary distribution provides everything you need to begin working with embedded database applications. After you download the binary distribution, you'll find a Java DB directory structure that contains the following subdirectories:

  • The demo subdirectory has two demonstration programs. One example shows how to create a trivial embedded application. The other shows how to use Java DB in a client-server environment.
  • The frameworks subdirectory contains utilities for setting up environment variables and for creating and working with databases. This directory is not useful for our demo because our application will be entirely self-contained. No outside utilities will be used for the Address Book application.
  • The javadoc subdirectory contains API documentation. This directory is particularly useful if you configure your IDE to point to it as the Java DB API Javadoc.
  • The docs subdirectory contains documentation about the Java DB product itself: setup, administrator, and reference guides.
  • Finally, the lib subdirectory contains the Java DB libraries packaged as JAR files. Read the Java DB documentation to find out about the various libraries. For an embedded database application, we will use only the derby.jar library file.

Installing Java DB for development requires only that you make the derby.jar file part of your application classpath. It's that simple. You can set the CLASSPATH variable of your Solaris, Linux, Windows, or other host environment to include the JAR file, or you can include the file as part of your command-line options when compiling or running. The Address Book demo's ANT script shows you how to include this JAR file during project development if you use ANT. Alternatively, some IDEs, including NetBeans IDE 5.0, let you configure classpaths.

Integrating Java DB With NetBeans IDE 5.0

Most IDEs provide a way to add libraries to the development classpath. Follow these instructions to add the Java DB libraries to NetBeans IDE 5.0:

  1. From the Tools menu, select Library Manager, as shown in Figure 2.

    Figure 2: The library manager lets you add third-party libraries to your project.
    Figure 2: The library manager lets you add third-party libraries to your project.
  2. In the Library Manager window, create a new library named JavaDBEmbedded, as shown in Figure 3. Click OK.
    Figure 3: Name the set of libraries that your project will need.
    Figure 3: Name the set of libraries that your project will need.
  3. To add the derby.jar file to the JavaDBEmbedded library, click on Add JAR/Folder... in the Library Manager window. Navigate the file chooser to the derby.jar file and select it as shown in Figure 4.
    Figure 4: Add the derby.jar file to the JavaDBEmbedded library.
    Figure 4: Add the derby.jar file to the JavaDBEmbedded library.
  4. In the same Library Manager window for the JavaDBEmbedded library, select the Javadoc tab. Add the javadoc subdirectory from your Java DB installation. Now, the Java DB API Javadoc is available when you use the JavaDBEmbedded library in your NetBeans IDE projects.

You can now add the JavaDBEmbedded library to your NetBeans IDE 5.0 project by using the project's property settings. When you compile, debug, and run the application within the IDE, the IDE will be able to find the needed derby.jar file.

To accommodate users of other IDEs, I have placed the derby.jar library within the lib subdirectory of the downloadable Address Book project. The accompanying ANT script can build and run the demo without any dependencies on the NetBeans IDE.

Loading the Database Driver

Loading the JDBC technology driver starts the database management system. Java DB's drivers come with the derby.jar file, so you don't need to download anything else. Load the JDBC driver by referencing it using the Class.forName method. The embedded driver name is org.apache.derby.jdbc.EmbeddedDriver, and you can load it as you would other JDBC drivers.

    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

The Address Book demo reads the driver name from a configuration property file and passes the name to a loadDriver method. Additionally, as mentioned earlier, Address Book encapsulates all database functionality into a Data Access Object (DAO), a core Java EE design pattern used to access data from a variety of sources. The DAO pattern works equally well for Java SE applications like Address Book. The following code snippet shows how AddressDao reads the driver name and loads the driver:

private Properties bProperties = null;
public AddressDao(String addressBookName) {
this.dbName = addressBookName;
setDBSystemDir();
dbProperties = loadDBProperties();
String driverName = dbProperties.getProperty("derby.driver");
loadDatabaseDriver(driverName);
...
}
private Properties loadDBProperties() {
InputStream dbPropInputStream = null;
dbPropInputStream =
AddressDao.class.getResourceAsStream("Configuration.properties");
dbProperties = new Properties();
try {
dbProperties.load(dbPropInputStream);
} catch (IOException ex) {
ex.printStackTrace();
}
return dbProperties;
}
private void loadDatabaseDriver(String driverName) {
// Load the Java DB driver.
try {
Class.forName(driverName);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
Connecting to the Java DB Database

A JDBC technology connection identifies a specific database and allows you to perform administrative tasks. Tasks include starting, stopping, copying, and even deleting a database. The driver manager provides all database connections.

Retrieve a connection from the driver manager by providing a URL string that identifies the database and a set of properties that influence the connection's interaction with the database. A very common use of properties is to associate a user name and password with a connection.

All connection URLs have the following form:

jdbc:derby:<dbName>[propertyList]

The dbName portion of the URL identifies a specific database. A database can be in one of many locations: in the current working directory, on the classpath, in a JAR file, in a specific Java DB database home directory, or in an absolute location on your file system. The easiest way to manage your database location in an embedded environment is to set the derby.system.home system property. This property tells Java DB the default home location of all databases. By setting this property, the Address Book demo ensures that Java DB always finds the correct application database. The application database is named DefaultAddressBook, and it will exist within the directory indicated by the derby.system.home property. The connection URL for this database would look like this:

jdbc:derby:DefaultAddressBook

The optional propertyList is a set of properties that you can pass to the database system. You can pass properties into the Java DB system either on the URL itself or as a separate Properties object. If properties are part of the URL, a semicolon (;) should precede each property. The most common properties are these:

  • create=true
  • databaseName=nameOfDatabase
  • user=userName
  • password=userPassword
  • shutdown=true

To connect to the DefaultAddressBook database, the demo must first set the derby.system.home system property. The demo uses the .addressbook subdirectory of the user's home directory. Use the System class to find out the user's home directory. Then use the class again to set the derby.system.home property:

private void setDBSystemDir() {
// Decide on the db system directory: <userhome>/.addressbook/
String userHomeDir = System.getProperty("user.home", ".");
String systemDir = userHomeDir + "/.addressbook";
// Set the db system directory.
System.setProperty("derby.system.home", systemDir);
}

Once the application has specified where all databases will exist, it can retrieve a database connection. In this example, notice that I have appended connection properties to the database URL.

Connection dbConnection = null;
String strUrl = "jdbc:derby:DefaultAddressBook;user=dbuser;password=dbuserpwd";
try {
dbConnection = DriverManager.getConnection(strUrl);
} catch (SQLException sqle) {
sqle.printStackTrace();
}

Alternatively, you can put those properties into a Properties object. Pass the Properties object as an argument when retrieving a connection:

Connection dbConnection = null;
String strUrl = "jdbc:derby:DefaultAddressBook";
Properties props = new Properties();
props.put("user", "dbuser");
props.put("password", "dbuserpwd");
try {
dbConnection = DriverManager.getConnection(strUrl, props);
} catch(SQLException sqle) {
sqle.printStackTrace();
}
Creating the Database

The Address Book demo application does not have a ready-made database. Instead, the application must create the database when it starts. One of the biggest advantages of using an embedded database is that the application -- not the user -- takes care of the details of setting up a database. The application can control where the database exists, what tables exist, and how permissions are handled.

Address Book creates a database called DefaultAddressBook in a subdirectory of the user's home directory, and it does so without asking the user for any additional information. You can create a new database in Java DB by using the create=true property when retrieving a connection to a database. Because our application will use the DefaultAddressBook database, we should first create this database. Assuming that the application has already set the derby.system.home property as discussed earlier, the application creates the database and connects to it like this:

Connection dbConnection = null;
String strUrl = "jdbc:derby:DefaultAddressBook;create=true";
try {
dbConnection = DriverManager.getConnection(strUrl);
} catch (SQLException ex) {
ex.printStackTrace();
}

Because the create=true property is included, Java DB will attempt to create the database files for the first time. Creating the database doesn't actually create any application tables. However, you should now be able to find a new subdirectory named .addressbook/DefaultAddressBook in your home directory.

After it has created the database, the application creates the tables. The demo uses only one ADDRESS table in the default application APP schema. The following SQL code creates the ADDRESS table:

CREATE table APP.ADDRESS (
ID          INTEGER NOT NULL
PRIMARY KEY GENERATED ALWAYS AS IDENTITY
(START WITH 1, INCREMENT BY 1),
LASTNAME    VARCHAR(30),
FIRSTNAME   VARCHAR(30),
MIDDLENAME  VARCHAR(30),
PHONE       VARCHAR(20),
EMAIL       VARCHAR(30),
ADDRESS1    VARCHAR(30),
ADDRESS2    VARCHAR(30),
CITY        VARCHAR(30),
STATE       VARCHAR(30),
POSTALCODE  VARCHAR(20),
COUNTRY     VARCHAR(30) )

Each record has a record identifier or ID field. Java DB generates this value for each new record that it adds to the database. The ID field is the primary key for each address record.

All remaining address record fields contain varchar elements of various lengths. For example, the LASTNAME field can contain a maximum of 30 varchar characters. The varchar type is equivalent to a UTF-16 Java char code unit.

The Java technology code that uses the above SQL statement to create the ADDRESS table looks like the following code. The dbConnection is the same as the one shown in the previous code. We simply pass it into createTables, create a new Statement, and call the execute method to run the SQL code on the newly formed database. The strCreateAddressTable instance variable holds the SQL statement text.

private boolean createTables(Connection dbConnection) {
boolean bCreatedTables = false;
Statement statement = null;
try {
statement = dbConnection.createStatement();
statement.execute(strCreateAddressTable);
bCreatedTables = true;
} catch (SQLException ex) {
ex.printStackTrace();
}
return bCreatedTables;
}

At this point, the database and the ADDRESS table exist in a subdirectory named .addressbook/DefaultAddressBook in your home directory. Although you can browse this subdirectory, avoid modifying any files. If you edit or delete any of these database files directly, you can destroy the integrity of your database.

Using the Database

Once the database and its tables have been created, your application can create new connections and statements to add, edit, delete, or retrieve records. In Address Book, these actions are controlled by buttons within the AddressActionPanel. Figure 5 shows the available options:

  • New. Create a new address record.
  • Delete. Delete the displayed address record.
  • Edit. Edit the displayed address record.
  • Save. Save the new or edited address record that is displayed.
  • Cancel. Cancel any edits or any attempt to create a new record.
Figure 5: Address Book has several options for interacting with records.
Figure 5: Address Book has several options for interacting with records.

The main window of the application is AddressFrame, which acts as a controller and as a view at the same time. It registers itself with the AddressActionPanel to receive notification when a user clicks anywhere on the action bar.

The New command clears the address entry panel and enables the user to edit all fields. No SQL commands are issued at this point, but the UI should allow you to enter a new address.

The Delete command attempts to delete the currently selected address record. AddressFrame retrieves the currently selected Address identifier from the AddressPanel and uses AddressDao to delete the record. The panel calls its own deleteAddress method, which calls the DAO's deleteRecord method with the correct ID. After deleting the record from the database, the application must delete the ListEntry from the AddressListPanel too.

private void deleteAddress() {
int id = addressPanel.getId();
if (id != -1) {
db.deleteRecord(id);
int selectedIndex = addressListPanel.deleteSelectedEntry();
...
}
...
}

In the AddressDao, the deleteRecord method handles the actual deletion of the record from the database. The AddressDao creates a PreparedStatement when it first connects to the database.

stmtDeleteAddress = dbConnection.prepareStatement(
"DELETE FROM APP.ADDRESS " +
"WHERE ID = ?");

The PreparedStatement can be used multiple times, and this one uses a parameter to determine which record to delete. The deleteRecord method executes the update after setting the ID parameter:

public boolean deleteRecord(int id) {
boolean bDeleted = false;
try {
stmtDeleteAddress.clearParameters();
stmtDeleteAddress.setInt(1, id);
stmtDeleteAddress.executeUpdate();
bDeleted = true;
} catch (SQLException sqle) {
sqle.printStackTrace();
}
return bDeleted;
}

The Edit command allows the user to edit the currently selected Address record in the AddressPanel. For example, you can change the name, city, or phone number of a saved record.

The Save command retrieves either the newly created or edited Address from the AddressPanel and attempts to either update the existing record or create a new record. If the user has been editing a record, Save will update that record with the new information. If the user has created a new record, Save will insert a new record in the database. New records have not yet been saved. At this point, their ID field is still set to the default -1 value. This value changes to an autogenerated, unique record identifier once you save the record.

The following code in AddressFrame will save edited and newly created address records by calling the DAO's editRecord or saveRecord method, respectively. Of course, when you create a new record, the application must also update the AddressListPanel.

private void saveAddress() {
if (addressPanel.isEditable()) {
Address address = addressPanel.getAddress();
int id = address.getId();
if (id == -1) {
id = db.saveRecord(address);
address.setId(id);
String lname = address.getLastName();
String fname = address.getFirstName();
String mname = address.getMiddleName();
ListEntry entry = new ListEntry(lname, fname, mname, id);
addressListPanel.addListEntry(entry);
} else {
db.editRecord(address);
}
addressPanel.setEditable(false);
}
}

The DAO's editRecord method must update the fields that change in the Address record. Because the demo application doesn't distinguish between edited and unedited fields, it simply updates all fields in the record. Following are the PreparedStatement object and the editRecord method:

stmtUpdateExistingRecord = dbConnection.prepareStatement(
"UPDATE APP.ADDRESS " +
"SET LASTNAME = ?, " +
"    FIRSTNAME = ?, " +
"    MIDDLENAME = ?, " +
"    PHONE = ?, " +
"    EMAIL = ?, " +
"    ADDRESS1 = ?, " +
"    ADDRESS2 = ?, " +
"    CITY = ?, " +
"    STATE = ?, " +
"    POSTALCODE = ?, " +
"    COUNTRY = ? " +
"WHERE ID = ?");
...
public boolean editRecord(Address record) {
boolean bEdited = false;
try {
stmtUpdateExistingRecord.clearParameters();
stmtUpdateExistingRecord.setString(1, record.getLastName());
stmtUpdateExistingRecord.setString(2, record.getFirstName());
stmtUpdateExistingRecord.setString(3, record.getMiddleName());
stmtUpdateExistingRecord.setString(4, record.getPhone());
stmtUpdateExistingRecord.setString(5, record.getEmail());
stmtUpdateExistingRecord.setString(6, record.getAddress1());
stmtUpdateExistingRecord.setString(7, record.getAddress2());
stmtUpdateExistingRecord.setString(8, record.getCity());
stmtUpdateExistingRecord.setString(9, record.getState());
stmtUpdateExistingRecord.setString(10, record.getPostalCode());
stmtUpdateExistingRecord.setString(11, record.getCountry());
stmtUpdateExistingRecord.setInt(12, record.getId());
stmtUpdateExistingRecord.executeUpdate();
bEdited = true;
} catch(SQLException sqle) {
sqle.printStackTrace();
}
return bEdited;
}

Saving a new Address creates a new database record, and that new record has a new primary key or record identifier. When we create the PreparedStatement, we can tell the database that we want to know the generated keys. Notice how we can retrieve a ResultSet of generated keys after inserting the record. The saveRecord method returns the primary key of the newly created record.

stmtSaveNewRecord = dbConnection.prepareStatement(
"INSERT INTO APP.ADDRESS " +
"   (LASTNAME, FIRSTNAME, MIDDLENAME, " +
"    PHONE, EMAIL, ADDRESS1, ADDRESS2, " +
"    CITY, STATE, POSTALCODE, COUNTRY) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
...
public int saveRecord(Address record) {
int id = -1;
try {
stmtSaveNewRecord.clearParameters();
stmtSaveNewRecord.setString(1, record.getLastName());
stmtSaveNewRecord.setString(2, record.getFirstName());
stmtSaveNewRecord.setString(3, record.getMiddleName());
stmtSaveNewRecord.setString(4, record.getPhone());
stmtSaveNewRecord.setString(5, record.getEmail());
stmtSaveNewRecord.setString(6, record.getAddress1());
stmtSaveNewRecord.setString(7, record.getAddress2());
stmtSaveNewRecord.setString(8, record.getCity());
stmtSaveNewRecord.setString(9, record.getState());
stmtSaveNewRecord.setString(10, record.getPostalCode());
stmtSaveNewRecord.setString(11, record.getCountry());
int rowCount = stmtSaveNewRecord.executeUpdate();
ResultSet results = stmtSaveNewRecord.getGeneratedKeys();
if (results.next()) {
id = results.getInt(1);
}
} catch(SQLException sqle) {
sqle.printStackTrace();
}
return id;
}
Deploying Your Application

Now that you have written the application, you must deploy it to users. Java technology applications can use a variety of deployment strategies, including Java Web Start software, applets, and stand-alone JAR files. I distribute the Address Book application as a stand-alone application with JAR files.

The ANT build file, build.xml, uses a dist target to create AddressBook.jar. It also places the database JAR file in the lib subdirectory directly under the AddressBook.jar location. The final distribution structure for the application looks like this:

AddressBook.jar
lib/derby.jar

In many cases, applications that use third-party libraries such as derby.jar require an external script to run. The script usually places the third-party JAR files on the classpath and then executes the application from its JAR. This method is troublesome, however, because it requires multiple scripts, typically one for each supported host operating system. For example, to support distribution on Windows, Solaris, and Linux platforms, I would create a run.bat batch file for the Windows platform and a run.csh script for a Solaris or Linux platform. Instead, we can avoid these clumsy execution scripts.

If our build process includes classpath information in the AddressBook.jar manifest file, you can run the application by simply passing the AddressBook.jar file on the execution command line. On most platforms, you can also just double-click on the JAR file name in a graphical window. On a command line, you can use this simple execution command:

java -jar AddressBook.jar

This simple deployment and execution scenario can be accomplished by creating a manifest.mf file that becomes part of the AddressBook.jar file. You can include information in the manifest that tells the Java programming language interpreter which class contains the main method and what other JAR files should become part of the classpath. The following manifest does both, and we can include it when building AddressBook.jar.

Manifest-Version: 1.0
Main-Class: com.sun.demo.addressbook.AddressFrame
Class-Path: lib/derby.jar

Once your build process generates the application distribution structure shown previously, you can simply distribute this structure as a ZIP file. Users can simply unzip the file into any location and run the AddressBook.jar file. The AddressBook.jar file will contain the manifest file mentioned earlier and will tell your runtime environment what JAR files should also be on the classpath. Of course, because Java DB is embedded into this application, it must be able to find lib/derby.jar in order to run correctly.

Summary

Working with Java DB is easy and fun. Java DB makes it possible to create and distribute an embedded database with minimal effort. Just remember a few tips to make your work with Java DB successful:

  1. Place the derby.jar file in your development environment's classpath so that your Java technology compiler and runtime environment can find the libraries to compile and run the application.
  2. Set the derby.system.home system property to tell Java DB where to find your database. You can set this property programmatically or on the command line.
  3. Create a build process that places the derby.jar file in a lib subdirectory immediately below your application's own directory.
  4. Add derby.jar to the application classpath by including a Class-Path property in your application JAR's manifest file.

桌面程序使用JavaDB相关推荐

  1. pyqt designer connect无响应_如何用PyQt编写桌面程序,创建并打开播放列表?

    由于电脑上的短视频太多了,并且分别存放在各个子目录下,每次更新后想要整理视频比较麻烦,因此想用Python编写程序来辅助管理视频文件.其实写个Python脚本程序即可实现大器的需求,但为了多练习PyQ ...

  2. Nativefier 网页转桌面程序 app

    Nativefier 网页转桌面程序 Nativefier简介 Nativefier是一个命令行工具,仅仅通过一行代码就可以轻松地为任何的网站创建桌面应用程序,应用程序通过Electron打包成系统可 ...

  3. 桌面程序调用Web Service应用实例

    作者:朱金灿 来源:blog.csdn.net/clever101 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com ...

  4. SharpUpdater:开源的.NET桌面程序自动更新组件

    SharpUpdater开源了! http://sharpupdater.codeplex.com/ 简  介 SharpUpdater是一个开源的.NET Windows桌面程序自动更新的组件.它提 ...

  5. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案 参考文章: (1)C#/.NET基于Topshelf创建Windows ...

  6. python可以写桌面软件吗-python能写桌面程序吗

    其实Python/Java/PHP都不适合用来做桌面开发,Java还是有几个比较成熟的产品的,比如大名鼎鼎的Java集成开发环境IntelliJ IDEA.Eclipse就是用Java开发的,不过PH ...

  7. 【Qt】Qt 开发桌面程序 ( Qt 版本 5.14.2 | 编辑 Qt 桌面按钮控件 | 修改按钮文本 | 为按钮添加点击事件 | 系统调用 | 去掉系统调用命令窗口 )

    文章目录 一.添加按钮控件 二.修改按钮文本 三.为按钮添加点击事件 ( 弹出对话框 ) 四.为按钮添加点击事件 ( 打开记事本 ) 五.为按钮添加点击事件 ( 打开计算器 ) 六.去掉系统调用时弹出 ...

  8. 【OpenGL】二十四、OpenGL 纹理贴图 ( 读取文件内容 | 桌面程序添加控制台窗口 | ‘fopen‘: This function may be unsafe 错误处理 )

    文章目录 一.文件读取 二.报错处理 ( 'fopen': This function or variable may be unsafe. ) 三.桌面程序添加控制台窗口 四.相关资源 一.文件读取 ...

  9. 【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )

    文章目录 一.导入头文件 二.桌面程序入口函数 三.注册窗口 四.创建窗口 五.显示窗口 六.完整代码示例 七.相关资源 基于 [OpenGL]一.Visual Studio 2019 创建 Wind ...

最新文章

  1. C# 四舍五入round函数使用的代码
  2. python tqdm进度条打印
  3. Oracle10g备份集压缩新特性(Backupset Compression)
  4. java中让数据生成excle文件并且支持下载
  5. 【树链剖分】【线段树】树的统计(金牌导航 树链剖分-1)
  6. voxelnet_苹果最新机器学习论文:使用VoxelNet进行3D物体检测
  7. 第二季-专题5-核心初始化
  8. [Stage3D]入门讲稿
  9. 鸿蒙系统能玩魔兽世界吗,苹果M1可以玩魔兽世界吗 M1芯片能玩魔兽吗
  10. 【06年博文搬家】查看本机的瑞星序列号
  11. iOS 在CollectionView上做展开收起动画
  12. Screenpresso-截图工具绿色版
  13. Grounded theory相关知识
  14. js常用工具类(1)
  15. vgs是什么意思有什么用_Linux中vgs命令起什么作用呢?
  16. Apache Dubbo详解
  17. Qt报错:cc1plus.exe: out of memory allocating 65536 bytes
  18. sqlserver设计表不允许保存更改,阻止保存要求重新创建表的更改
  19. 【图神经网络】图神经网络(GNN)学习笔记:图分类
  20. 老年性痴呆,需要心理关爱

热门文章

  1. LeetCode——658. 找到 K 个最接近的元素(双指针)
  2. ansible file 模块
  3. 《编写高质量代码 改善python程序的91个建议》读书笔记 之一
  4. 【点云压缩】点云概述:点云的分类与处理 点云来源
  5. 僵尸索引 Dangling indices
  6. kali安装java8
  7. 写个小程序有效突破SAT词汇关
  8. webpack构建之tree-shaking的原理是什么
  9. Airbnb爱彼迎推出看得见“春色”的房源
  10. proxy代理 显示404 但请求方式、服务器地址都对