Josiah Yoder
Josiah Yoder

Reputation: 3756

How to copy packages in IntelliJ without creating numerous fully-specified links to the old package

To readers who like this question: I asked this question eight years ago (as of 2022) and there are only three upvotes. Please be aware that there are not many of us who need this feature and it is unlikely this will be supported by IntelliJ (or any modern IDE) for the foreseeable future.


When I use IntelliJ to copy a package which contains subpackages, every internal references to other classes in the same package is converted to an ugly fully-qualified name. Worse yet, this fully-qualified name links back to the old package instead of to the copied class in the new package! Does anyone know a workaround for this problem?

To reproduce this problem, I create a project structure like this:

"example" folder containing an empty folder "subpackage" and two Java files "A.java" and "B.java"

Where A.java is:

package example;

public class A { }

And B. java is: package example;

public class B {
    private A a;
    public B(A a) {
        this.a = a;
    }
}

I then Ctrl-C and Ctrl-V the example folder, and edit the dialog as below: Dialog with example renamed to example2

The copied version of classB now has every instance of A replaced with example.A package example2;

import example.*;

public class B {
    private example.A a;
    public B(example.A a) {
        this.a = a;
    }
}

Does anyone have a suggested work-around to avoid this behavior, and simple change the package name, leaving everything else alone? Thanks!

P.S. While version control is usually the best way to track different versions of a program, I want to create an actual copy in this case. I use IntelliJ for teaching programming, and I create multiple versions of small, multi-packaged programs demonstrating how the program improves as I model refactoring techniques.

[Reported on Jet Brains here] 3.

Upvotes: 3

Views: 3905

Answers (5)

Diana
Diana

Reputation: 1

Here is an effortless way (which works for sub packages that are in the same project or in different projects). Suppose we want to copy from Project1 to Project2 and we have the following structure (i.e. we want to copy the Car and Main classes in SubPackage21):

  1. Project1
    1. Package1
      1. SubPackage11
        1. Car.java
        2. Main.java
  2. Project2
    1. Package2
      1. SubPackage21

Step 1

Right-click on SubPackage21, click "Show in Explorer", and copy the path. It will be something like "...\Package2".

Step 2

Click on SubPackage11, press F5, paste the path and press "Enter".

You will get the following:

  1. Project2
    1. Package2
      1. SubPackage21
      2. SubPackage11
        1. Car.java
        2. Main.java

Step 3

Drag and drop the classes from SubPackage11 to SubPackage21, and press "Refactor" for all of them (this way the package name is replaced with the correct one, and no strange imports are added).

Upvotes: 0

Hrozhek
Hrozhek

Reputation: 11

Nothing of these were helpful for me, but I found a 100% working method. I had a structure like this:

package hometask1, 
package hometask2, 
package hometaskN, 

where each next package has the previous package's classes as a base and has some new features with some classes changed. When I copied the previous package hometask(N-1) to the next hometaskN, it would have the previous package's (hometask(N-1)) import statements. I found that I have solved my problem following these steps:

  1. Add new (temporary) project.
  2. Create package with name equals previous package (for example, hometask1).
  3. Copy classes from old project hometask1 to temp project hometask1.
  4. Create package with necessary name in temporary project (for example, hometask2).
  5. Move (not copy) all included packages and classes from temp hometask1 to temp hometask2. All imports are correct now.
  6. Create in old project package with same name (hometask2).
  7. Move or copy classes from temp hometask2 to main project hometask2.

Done.

Upvotes: 1

Josiah Yoder
Josiah Yoder

Reputation: 3756

My latest workaround:

  1. Set up IntelliJ to show excluded packages
  2. Exclude the package to be copied (e.g. example)
  3. Rename the package to be copied to a temporary name (e.g. example_temp). Ignore the warning about names not being updated.
  4. Copy the package into the src folder. Rename it to the original name (e.g. example) during the copy. Since the original name is no longer excluded, the package will reappear.
  5. Rename the copy to the new name. (e.g. rename example to example_v2)
  6. Rename the temporary file back to the original (e.g. rename example_temp to example)
  7. Remove the exclusion on the original directory (e.g. right-click example_temp->Mark directory as->Cancel Exclusion.)

Upvotes: 1

DroidCrafter
DroidCrafter

Reputation: 136

Try copy/paste using the mouse. This method is slow but works. 1. Open the dir. you want to copy from. 2. Click on the class you want to copy. 3. Copy it. 4. In the new package, click on the dir where you need to put the class. 5. Click paste.

You may also need to update the imports to reflect the new dir.

Upvotes: 0

Pavel Parshin
Pavel Parshin

Reputation: 517

You can try this:

  1. Select class A and class B in the Project Structure;
  2. Press F5;
  3. In opened window enter new path, for example, C:\projects\other\src\example2;
  4. Click Ok.

Upvotes: 1

Related Questions