mirror of
https://github.com/bronson-g/pdfCombiner.git
synced 2025-12-23 22:18:04 -05:00
first commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.iml
|
||||
.idea/
|
||||
target/
|
||||
89
pom.xml
Normal file
89
pom.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.ingvonic</groupId>
|
||||
<artifactId>pdfCombiner</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.15</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<finalName>PdfCombiner</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>PdfCombiner</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>org.apache.pdfbox:pdfbox</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>commons-logging:commons-logging</artifact>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
|
||||
<overWriteReleases>true</overWriteReleases>
|
||||
<overWriteSnapshots>true</overWriteSnapshots>
|
||||
<overWriteIfNewer>true</overWriteIfNewer>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
95
src/main/java/FileJList.java
Normal file
95
src/main/java/FileJList.java
Normal file
@@ -0,0 +1,95 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A JList that has files as elements, and can be reordered via drag and drop.
|
||||
*
|
||||
* created on 2019-07-05
|
||||
*/
|
||||
class FileJList extends JList<String> {
|
||||
|
||||
private DefaultListModel<String> view;
|
||||
private List<File> model;
|
||||
|
||||
FileJList() {
|
||||
super();
|
||||
|
||||
view = new DefaultListModel<>();
|
||||
model = new ArrayList<>();
|
||||
|
||||
setModel(view);
|
||||
setDragEnabled(true);
|
||||
setDropMode(DropMode.INSERT);
|
||||
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
setTransferHandler(new DragAndDrop());
|
||||
}
|
||||
|
||||
List<File> getElements() {
|
||||
return new ArrayList<>(model);
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return model.isEmpty() && view.isEmpty();
|
||||
}
|
||||
|
||||
void addElement(int i, File file) {
|
||||
model.add(i, file);
|
||||
view.addElement(file.getName());
|
||||
}
|
||||
|
||||
void addElement(File file) {
|
||||
model.add(file);
|
||||
view.addElement(file.getName());
|
||||
}
|
||||
|
||||
File getElement(int i) {
|
||||
return model.get(i);
|
||||
}
|
||||
|
||||
File removeElement(int i) {
|
||||
view.remove(i);
|
||||
return model.remove(i);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
view.clear();
|
||||
model.clear();
|
||||
}
|
||||
|
||||
private class DragAndDrop extends TransferHandler {
|
||||
private int index;
|
||||
|
||||
@Override
|
||||
public int getSourceActions(JComponent comp) {
|
||||
return MOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transferable createTransferable(JComponent comp) {
|
||||
index = getSelectedIndex();
|
||||
return new StringSelection(getSelectedValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportDone(JComponent comp, Transferable trans, int action) {
|
||||
removeElement(action == MOVE ? index + 1 : index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canImport(TransferHandler.TransferSupport support) {
|
||||
return support.isDataFlavorSupported(DataFlavor.stringFlavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importData(TransferHandler.TransferSupport support) {
|
||||
JList.DropLocation dl = (JList.DropLocation) support.getDropLocation();
|
||||
addElement(dl.getIndex(), model.get(index));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
135
src/main/java/PdfCombiner.java
Normal file
135
src/main/java/PdfCombiner.java
Normal file
@@ -0,0 +1,135 @@
|
||||
import org.apache.pdfbox.io.MemoryUsageSetting;
|
||||
import org.apache.pdfbox.multipdf.PDFMergerUtility;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Simple GUI to quickly merge multiple pdf files into a single pdf file.
|
||||
*
|
||||
* created on 2019-06-25
|
||||
*/
|
||||
public class PdfCombiner extends JFrame {
|
||||
private FileJList list;
|
||||
private JFileChooser chooser;
|
||||
|
||||
public static void main(String... args) {
|
||||
EventQueue.invokeLater(PdfCombiner::new);
|
||||
}
|
||||
|
||||
private PdfCombiner() {
|
||||
chooser = new JFileChooser();
|
||||
list = new FileJList();
|
||||
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Portable Document Format", "pdf"));
|
||||
|
||||
setTitle("PDF Combiner");
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
initialize();
|
||||
|
||||
pack();
|
||||
|
||||
setMinimumSize(getSize());
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
JScrollPane scroller = new JScrollPane();
|
||||
scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
scroller.setViewportView(list);
|
||||
scroller.setMinimumSize(new Dimension(100, 100));
|
||||
|
||||
add(scroller, BorderLayout.CENTER);
|
||||
|
||||
JPanel bottom = new JPanel(new GridLayout());
|
||||
|
||||
JButton addButton = new JButton("+");
|
||||
addButton.addActionListener(l -> add());
|
||||
bottom.add(addButton);
|
||||
|
||||
JButton removeButton = new JButton("-");
|
||||
removeButton.addActionListener(l -> remove());
|
||||
bottom.add(removeButton);
|
||||
|
||||
JButton clearButton = new JButton("Clear");
|
||||
clearButton.addActionListener(l -> list.clear());
|
||||
bottom.add(clearButton);
|
||||
|
||||
JButton saveButton = new JButton("Save");
|
||||
saveButton.addActionListener(l -> save());
|
||||
bottom.add(saveButton);
|
||||
|
||||
add(bottom, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
int[] indices = list.getSelectedIndices();
|
||||
|
||||
if(!list.isEmpty() && indices.length > 0) {
|
||||
Arrays.sort(indices);
|
||||
|
||||
for(int i = indices.length - 1; i >= 0; i--) {
|
||||
list.removeElement(indices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void save() {
|
||||
if(!list.isEmpty()) try {
|
||||
PDFMergerUtility merger = new PDFMergerUtility();
|
||||
for(File pdf : list.getElements()) {
|
||||
merger.addSource(pdf);
|
||||
}
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.showSaveDialog(this);
|
||||
|
||||
String fileName = chooser.getSelectedFile().getAbsolutePath();
|
||||
|
||||
if(!fileName.toLowerCase().endsWith(".pdf")) {
|
||||
fileName += ".pdf";
|
||||
}
|
||||
|
||||
merger.setDestinationFileName(fileName);
|
||||
merger.mergeDocuments(MemoryUsageSetting.setupTempFileOnly());
|
||||
} catch(FileNotFoundException e) {
|
||||
warn("One or more of the selected files could not be found.");
|
||||
} catch(IOException e) {
|
||||
warn("An error occurred while saving.");
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
warn("No PDFs were provided.");
|
||||
}
|
||||
}
|
||||
|
||||
private void add() {
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
chooser.showOpenDialog(this);
|
||||
|
||||
for(File pdf : chooser.getSelectedFiles()) {
|
||||
if(!list.getElements().contains(pdf)) {
|
||||
list.addElement(pdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void warn(String message) {
|
||||
JOptionPane.showConfirmDialog(
|
||||
this,
|
||||
message,
|
||||
"Error",
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE,
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user